1 use super::tty_ldisc::LineDisciplineType; 2 3 /// ## 窗口大小 4 #[repr(C)] 5 #[derive(Debug, Clone, Copy, PartialEq)] 6 pub struct WindowSize { 7 /// 行 8 pub row: u16, 9 /// 列 10 pub col: u16, 11 /// x方向像素数 12 pub xpixel: u16, 13 /// y方向像素数 14 pub ypixel: u16, 15 } 16 17 impl WindowSize { 18 pub const DEFAULT: WindowSize = WindowSize::new(24, 80, 1, 1); 19 pub const fn new(row: u16, col: u16, xpixel: u16, ypixel: u16) -> Self { 20 Self { 21 row, 22 col, 23 xpixel, 24 ypixel, 25 } 26 } 27 } 28 29 impl Default for WindowSize { 30 fn default() -> Self { 31 Self::DEFAULT 32 } 33 } 34 35 #[derive(Debug, Clone, Copy)] 36 pub struct Termios { 37 pub input_mode: InputMode, 38 pub output_mode: OutputMode, 39 pub control_mode: ControlMode, 40 pub local_mode: LocalMode, 41 pub control_characters: [u8; CONTORL_CHARACTER_NUM], 42 pub line: LineDisciplineType, 43 pub input_speed: u32, 44 pub output_speed: u32, 45 } 46 47 #[derive(Clone, Copy, Default)] 48 pub struct PosixTermios { 49 pub c_iflag: u32, 50 pub c_oflag: u32, 51 pub c_cflag: u32, 52 pub c_lflag: u32, 53 pub c_cc: [u8; CONTORL_CHARACTER_NUM], 54 pub c_line: u8, 55 pub c_ispeed: u32, 56 pub c_ospeed: u32, 57 } 58 59 impl PosixTermios { 60 pub fn from_kernel_termios(termios: Termios) -> Self { 61 Self { 62 c_iflag: termios.input_mode.bits, 63 c_oflag: termios.output_mode.bits, 64 c_cflag: termios.control_mode.bits, 65 c_lflag: termios.local_mode.bits, 66 c_cc: termios.control_characters, 67 c_line: termios.line as u8, 68 c_ispeed: termios.input_speed, 69 c_ospeed: termios.output_speed, 70 } 71 } 72 73 pub fn to_kernel_termios(self) -> Termios { 74 // TODO:这里没有考虑非规范模式 75 Termios { 76 input_mode: InputMode::from_bits_truncate(self.c_iflag), 77 output_mode: OutputMode::from_bits_truncate(self.c_oflag), 78 control_mode: ControlMode::from_bits_truncate(self.c_cflag), 79 local_mode: LocalMode::from_bits_truncate(self.c_lflag), 80 control_characters: self.c_cc, 81 line: LineDisciplineType::from_line(self.c_line), 82 input_speed: self.c_ispeed, 83 output_speed: self.c_ospeed, 84 } 85 } 86 } 87 88 pub const INIT_CONTORL_CHARACTERS: [u8; CONTORL_CHARACTER_NUM] = [ 89 b'C' - 0x40, // VINTR 90 b'\\' - 0x40, // VQUIT 91 0o177, // VERASE 92 b'U' - 0x40, // VKILL 93 b'D' - 0x40, // VEOF 94 1, // VMIN 95 0, // VEOL 96 0, // VTIME 97 0, // VEOL2 98 0, // VSWTC 99 b'W' - 0x40, // VWERASE 100 b'R' - 0x40, // VREPRINT 101 b'Z' - 0x40, // VSUSP 102 b'Q' - 0x40, // VSTART 103 b'S' - 0x40, // VSTOP 104 b'V' - 0x40, // VLNEXT 105 b'O' - 0x40, // VDISCARD 106 0, 107 0, 108 ]; 109 110 // pub const INIT_CONTORL_CHARACTERS: [u8; CONTORL_CHARACTER_NUM] = { 111 // let mut chs: [u8; CONTORL_CHARACTER_NUM] = Default::default(); 112 // chs[ControlCharIndex::VINTR] = b'C' - 0x40; 113 // chs[ControlCharIndex::VQUIT] = b'\\' - 0x40; 114 // chs[ControlCharIndex::VERASE] = 0o177; 115 // chs[ControlCharIndex::VKILL] = b'U' - 0x40; 116 // chs[ControlCharIndex::VEOF] = b'D' - 0x40; 117 // chs[ControlCharIndex::VSTART] = b'Q' - 0x40; 118 // chs[ControlCharIndex::VSTOP] = b'S' - 0x40; 119 // chs[ControlCharIndex::VSUSP] = b'Z' - 0x40; 120 // chs[ControlCharIndex::VREPRINT] = b'R' - 0x40; 121 // chs[ControlCharIndex::VDISCARD] = b'O' - 0x40; 122 // chs[ControlCharIndex::VWERASE] = b'W' - 0x40; 123 // chs[ControlCharIndex::VLNEXT] = b'V' - 0x40; 124 // // chs[ContorlCharIndex::VDSUSP] = b'Y' - 0x40; 125 // chs[ControlCharIndex::VMIN] = 1; 126 // return chs; 127 // }; 128 129 lazy_static! { 130 pub static ref TTY_STD_TERMIOS: Termios = { 131 Termios { 132 input_mode: InputMode::ICRNL | InputMode::IXON, 133 output_mode: OutputMode::OPOST | OutputMode::ONLCR, 134 control_mode: ControlMode::B38400 135 | ControlMode::CREAD 136 | ControlMode::HUPCL 137 | ControlMode::CS8, 138 local_mode: LocalMode::ISIG 139 | LocalMode::ICANON 140 | LocalMode::ECHO 141 | LocalMode::ECHOE 142 | LocalMode::ECHOK 143 | LocalMode::ECHOCTL 144 | LocalMode::ECHOKE 145 | LocalMode::IEXTEN, 146 control_characters: INIT_CONTORL_CHARACTERS, 147 line: LineDisciplineType::NTty, 148 input_speed: 38400, 149 output_speed: 38400, 150 } 151 }; 152 } 153 154 pub const CONTORL_CHARACTER_NUM: usize = 19; 155 156 bitflags! { 157 /// termios输入特性 158 pub struct InputMode: u32 { 159 /// 如果设置了该标志,表示启用软件流控制。 160 const IXON = 0x0400; 161 /// 如果设置了该标志,表示启用输入流控制。 162 const IXOFF = 0x1000; 163 /// Map Uppercase to Lowercase on Input 将大写转换为小写 164 /// 表示不区分大小写 165 const IUCLC = 0x0200; 166 /// 如果设置了该标志,表示当输入队列满时,产生一个响铃信号。 167 const IMAXBEL = 0x2000; 168 /// 如果设置了该标志,表示输入数据被视为 UTF-8 编码。 169 const IUTF8 = 0x4000; 170 171 /// 忽略中断信号 172 const IGNBRK = 0x001; 173 /// 检测到中断信号时生成中断(产生中断信号) 174 const BRKINT = 0x002; 175 /// 忽略具有奇偶校验错误的字符 176 const IGNPAR = 0x004; 177 /// 在检测到奇偶校验错误或帧错误时,将字符以 \377 标记 178 const PARMRK = 0x008; 179 /// 启用输入奇偶校验检查 180 const INPCK = 0x010; 181 /// 从输入字符中剥离第 8 位,即只保留低 7 位 182 const ISTRIP = 0x020; 183 /// 表示将输入的换行符 (\n) 映射为回车符 (\r) 184 const INLCR = 0x040; 185 /// 表示忽略回车符 (\r) 186 const IGNCR = 0x080; 187 /// 表示将输入的回车符 (\r) 映射为换行符 (\n) 188 const ICRNL = 0x100; 189 /// 表示在输入被停止(Ctrl-S)后,任何字符的输入都将重新启动输入 190 const IXANY = 0x800; 191 } 192 193 /// termios输出特性 194 pub struct OutputMode: u32 { 195 /// 在输出时将换行符替换\r\n 196 const ONLCR = 0x00004; 197 /// Map Lowercase to Uppercase on Output 输出字符时将小写字母映射为大写字母 198 const OLCUC = 0x00002; 199 200 /// 与NL协同 配置换行符的处理方式 201 const NLDLY = 0x00100; 202 const NL0 = 0x00000; // 不延迟换行 203 const NL1 = 0x00100; // 延迟换行(输出回车后等待一段时间再输出换行) 204 205 /// 配置水平制表符的处理方式 206 const TABDLY = 0x01800; 207 const TAB0 = 0x00000; // 不延迟水平制表符 208 const TAB1 = 0x00800; // 在输出水平制表符时,延迟到下一个设置的水平制表符位置 209 const TAB2 = 0x01000; // 在输出水平制表符时,延迟到下一个设置的 8 的倍数的位置 210 const TAB3 = 0x01800; // TAB3 和 XTABS(与 TAB3 等效)保留,暂未使用 211 const XTABS = 0x01800; 212 213 /// 配置回车符的处理方式 214 const CRDLY = 0x00600; 215 const CR0 = 0x00000; // 不延迟回车 216 const CR1 = 0x02000; // 延迟回车(输出回车后等待一段时间再输出换行) 217 const CR2 = 0x04000; // CR2 和 CR3保留,暂未使用 218 const CR3 = 0x06000; 219 220 /// 配置换页符(form feed)的处理方式 221 const FFDLY = 0x08000; 222 const FF0 = 0x00000; // 不延迟换页 223 const FF1 = 0x08000; // 延迟换页 224 225 /// 配置退格符(backspace)的处理方式 226 const BSDLY = 0x02000; 227 const BS0 = 0x00000; // 不延迟退格 228 const BS1 = 0x02000; // 延迟退格 229 230 /// 配置垂直制表符(vertical tab)的处理方式 231 const VTDLY = 0x04000; 232 const VT0 = 0x00000; // 不延迟垂直制表符 233 const VT1 = 0x04000; // 延迟垂直制表符 234 235 /// 表示执行输出处理,即启用输出处理函数 236 const OPOST = 0x01; 237 /// 表示将输出的回车符 (\r) 映射为换行符 (\n) 238 const OCRNL = 0x08; 239 /// 表示在输出时,如果光标在第 0 列,则不输出回车符 (\r) 240 const ONOCR = 0x10; 241 /// 表示将回车符 (\r) 映射为换行符 (\n) 242 const ONLRET = 0x20; 243 /// 表示使用填充字符进行延迟。这个填充字符的默认值是空格。 244 const OFILL = 0x40; 245 /// 表示使用删除字符 (DEL, \177) 作为填充字符 246 const OFDEL = 0x80; 247 } 248 249 /// 配置终端设备的基本特性和控制参数 250 pub struct ControlMode: u32 { 251 /// Baud Rate Mask 指定波特率的掩码 252 const CBAUD = 0x0000100f; 253 /// Extra Baud Bits 指定更高的波特率位 254 const CBAUDEX = 0x00001000; 255 /// Custom Baud Rate 指定自定义波特率 如果设置了 BOTHER,则通过以下位来设置自定义的波特率值 256 const BOTHER = 0x00001000; 257 258 /* Common CBAUD rates */ 259 const B0 = 0x00000000; /* hang up */ 260 const B50 = 0x00000001; 261 const B75 = 0x00000002; 262 const B110 = 0x00000003; 263 const B134 = 0x00000004; 264 const B150 = 0x00000005; 265 const B200 = 0x00000006; 266 const B300 = 0x00000007; 267 const B600 = 0x00000008; 268 const B1200 = 0x00000009; 269 const B1800 = 0x0000000a; 270 const B2400 = 0x0000000b; 271 const B4800 = 0x0000000c; 272 const B9600 = 0x0000000d; 273 const B19200 = 0x0000000e; 274 const B38400 = 0x0000000f; 275 276 const B57600 = 0x00001001; 277 const B115200 = 0x00001002; 278 const B230400 = 0x00001003; 279 const B460800 = 0x00001004; 280 const B500000 = 0x00001005; 281 const B576000 = 0x00001006; 282 const B921600 = 0x00001007; 283 const B1000000 = 0x00001008; 284 const B1152000 = 0x00001009; 285 const B1500000 = 0x0000100a; 286 const B2000000 = 0x0000100b; 287 const B2500000 = 0x0000100c; 288 const B3000000 = 0x0000100d; 289 const B3500000 = 0x0000100e; 290 const B4000000 = 0x0000100f; 291 292 /// 指定字符大小的掩码 以下位为特定字符大小 293 const CSIZE = 0x00000030; 294 const CS5 = 0x00000000; 295 const CS6 = 0x00000010; 296 const CS7 = 0x00000020; 297 const CS8 = 0x00000030; 298 299 /// Stop Bit Select 表示使用两个停止位;否则,表示使用一个停止位 300 const CSTOPB = 0x00000040; 301 /// 表示启用接收器。如果未设置,则禁用接收器。 302 const CREAD = 0x00000080; 303 /// 表示启用奇偶校验。如果未设置,则禁用奇偶校验。 304 const PARENB = 0x00000100; 305 /// 表示启用奇校验。如果未设置,则表示启用偶校验。 306 const PARODD = 0x00000200; 307 /// 表示在终端设备被关闭时挂断线路(执行挂断操作) 308 const HUPCL = 0x00000400; 309 /// 表示忽略调制解调器的状态(DCD、DSR、CTS 等) 310 const CLOCAL = 0x00000800; 311 /// 指定输入波特率的掩码 312 const CIBAUD = 0x100f0000; 313 314 const ADDRB = 0x20000000; 315 } 316 317 /// 配置终端设备的本地模式(local mode)或控制输入处理的行为 318 pub struct LocalMode: u32 { 319 /// 启用中断字符(Ctrl-C、Ctrl-Z) 320 const ISIG = 0x00001; 321 /// 表示启用规范模式,即启用行缓冲和回显。在规范模式下,输入被缓冲,并且只有在输入回车符时才会传递给应用程序。 322 const ICANON = 0x00002; 323 /// 表示启用大写模式,即输入输出都将被转换为大写。 324 const XCASE = 0x00004; 325 /// 表示启用回显(显示用户输入的字符) 326 const ECHO = 0x00008; 327 /// 表示在回显时将擦除的字符用 backspace 和空格字符显示。 328 const ECHOE = 0x00010; 329 /// 表示在回显时将换行符后的字符用空格字符显示。 330 const ECHOK = 0x00020; 331 /// 表示在回显时将换行符显示为换行和回车符。 332 const ECHONL = 0x00040; 333 /// 表示在收到中断(Ctrl-C)和退出(Ctrl-\)字符后,不清空输入和输出缓冲区。 334 const NOFLSH = 0x00080; 335 /// 表示在后台进程尝试写入终端时,发送停止信号(Ctrl-S) 336 const TOSTOP = 0x00100; 337 /// 表示在回显时,显示控制字符为 ^ 加字符。 338 const ECHOCTL= 0x00200; 339 /// 表示在回显时显示带有 # 的换行符(为了与 echo -n 命令兼容)。 340 const ECHOPRT= 0x00400; 341 /// 表示在回显时将 KILL 字符(Ctrl-U)用空格字符显示。 342 const ECHOKE = 0x00800; 343 /// 表示输出正在被冲刷(flush),通常是由于输入/输出流的状态变化。 344 const FLUSHO = 0x01000; 345 /// 表示在规范模式下,存在需要重新打印的字符。 346 const PENDIN = 0x04000; 347 /// 表示启用实现定义的输入处理。 348 const IEXTEN = 0x08000; 349 /// 表示启用扩展的处理函数 350 const EXTPROC= 0x10000; 351 } 352 353 pub struct TtySetTermiosOpt: u8 { 354 const TERMIOS_FLUSH =1; 355 const TERMIOS_WAIT =2; 356 const TERMIOS_TERMIO =4; 357 const TERMIOS_OLD =8; 358 } 359 } 360 361 /// 对应termios中控制字符的索引 362 pub struct ControlCharIndex; 363 #[allow(dead_code)] 364 impl ControlCharIndex { 365 pub const DISABLE_CHAR: u8 = b'\0'; 366 /// 中断信号 367 pub const VINTR: usize = 0; 368 /// 退出信号 369 pub const VQUIT: usize = 1; 370 /// 退格 371 pub const VERASE: usize = 2; 372 /// 终止输入信号 373 pub const VKILL: usize = 3; 374 /// 文件结束信号 \0? 375 pub const VEOF: usize = 4; 376 /// 指定非规范模式下的最小字符数 377 pub const VMIN: usize = 5; 378 /// 换行符 379 pub const VEOL: usize = 6; 380 /// 指定非规范模式下的超时时间 381 pub const VTIME: usize = 7; 382 /// 换行符 383 pub const VEOL2: usize = 8; 384 /// 未使用,保留 385 pub const VSWTC: usize = 9; 386 /// 擦除前一个单词 387 pub const VWERASE: usize = 10; 388 /// 重新打印整行 389 pub const VREPRINT: usize = 11; 390 /// 挂起信号 391 pub const VSUSP: usize = 12; 392 /// 启动输出信号 393 pub const VSTART: usize = 13; 394 /// 停止输出信号 395 pub const VSTOP: usize = 14; 396 /// 将下一个字符视为字面值,而不是特殊字符 397 pub const VLNEXT: usize = 15; 398 /// 对应于字符丢弃信号,用于丢弃当前输入的行 399 pub const VDISCARD: usize = 16; 400 } 401