diff --git a/include/tty.h b/include/tty.h index fb36009..e674370 100644 --- a/include/tty.h +++ b/include/tty.h @@ -27,13 +27,16 @@ #define TTY_STATE_WAIT_SPACE 2 /*010*/ #define TTY_STATE_DISPLAY 1 /*001*/ +#define MAXNUM_PARAM 16 +#define MAXNUM_PARAM_CH 100 + typedef struct n_tty { int driver_type; // 1-vga&kbd; 2-serial void *input_buf; void *output_buf; void (*write)(struct n_tty *tty, char ch); - int (*read)(struct n_tty *tty, char* buf, int nr); + int (*read)(struct n_tty *tty, char *buf, int nr); void (*recvbuf)(struct n_tty *tty, u32 ch); int (*ioctl)(struct n_tty *tty, u32 cmd, long arg); } NTTY; @@ -42,8 +45,7 @@ enum CSI_state { CSI_ESC, CSI_BRACKET, - CSI_PARAM1, - CSI_PARAM2 + CSI_PARAM }; typedef struct vga_buf { @@ -56,14 +58,13 @@ typedef struct vga_buf int cur_row; int cur_col; // cursor position, on screen - bool Is2param; bool IsColorReverse; bool IsHide; enum CSI_state CSI; - i16 param1; // the first param of CSI - i16 param2; // the second of CSI + char param_c[MAXNUM_PARAM_CH]; // the params of CSI + u16 param_num; u16 color; u16 last_color; // 为了某些功能关闭后,恢复原属性 } vga_buf; @@ -115,8 +116,8 @@ extern NTTY *cur_ntty; #define IOCTL_CMD_TTY_SELECTCON 2 #define IOCTL_CMD_TTY_FLUSH 3 -#define TTY_SCROLL_UP 1 -#define TTY_SCROLL_DOWN 2 -#define TTY_SCROLL_TOCUR 3 +#define TTY_SCROLL_UP 1 +#define TTY_SCROLL_DOWN 2 +#define TTY_SCROLL_TOCUR 3 #endif /* _ORANGES_TTY_H_ */ \ No newline at end of file diff --git a/kernel/csi.c b/kernel/csi.c index c45cf04..955cbfe 100644 --- a/kernel/csi.c +++ b/kernel/csi.c @@ -212,148 +212,71 @@ disable_hide(vga_buf *vgabuf) } } -void set_color(vga_buf *vgabuf) +void set_color(i16 param_cnt, i16 param[], vga_buf *vgabuf) { - if (vgabuf->param1 == 0) + for (int i = 0; i <= param_cnt; i++) { - disable_reverse(vgabuf); - disable_hide(vgabuf); - vgabuf->color = DEFAULT_CHAR_COLOR; - } - else if (vgabuf->param1 == 7) - { - enable_reverse(vgabuf); - } - else if (vgabuf->param1 == 8) - { - enable_hide(vgabuf); - } - else if (vgabuf->param1 == 25) - { - disable_blink(); - vgabuf->color &= (~FLASH_CHAR); - } - else if (vgabuf->param1 == 27) - { - disable_reverse(vgabuf); - } - else if (vgabuf->param1 == 28) - { - disable_hide(vgabuf); - } - else if (30 <= vgabuf->param1 && vgabuf->param1 <= 37) - { - vgabuf->param1 -= 30; - param12vga_color(&(vgabuf->param1)); - vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param1); - } - else if (vgabuf->param1 == 39) - { - u16 default_foreground = DEFAULT_CHAR_COLOR & 0x0f00; - vgabuf->color = (vgabuf->color & 0xf0ff) | default_foreground; - } - else if (40 <= vgabuf->param1 && vgabuf->param1 <= 47) - { - vgabuf->param1 -= 40; - param12vga_color(&(vgabuf->param1)); - vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param1); - } - else if (vgabuf->param1 == 49) - { - u16 default_background = DEFAULT_CHAR_COLOR & 0xf000; - vgabuf->color = (vgabuf->color & 0x0fff) | default_background; - } - else if (90 <= vgabuf->param1 && vgabuf->param1 <= 97) - { - vgabuf->param1 -= 90; - param12vga_color(&(vgabuf->param1)); - vgabuf->param1 |= 0x8; - vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param1); - } - else if (100 <= vgabuf->param1 && vgabuf->param1 <= 107) - { - vgabuf->param1 -= 100; - param12vga_color(&(vgabuf->param1)); - vgabuf->param1 |= 0x8; - vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param1); - } - else - { - warn("\x1b[47;93munsupport CSI: sgr param:%d\x1b[m\n", vgabuf->param1); - } - if (vgabuf->Is2param == true) - { - if (vgabuf->param2 == 0) + if (param[i] == 0) { disable_reverse(vgabuf); disable_hide(vgabuf); vgabuf->color = DEFAULT_CHAR_COLOR; } - // else if (vgabuf->param2 == 5 || vgabuf->param2 == 6) - // { - // enable_blink(); - // vgabuf->color |= FLASH_CHAR; - // } - else if (vgabuf->param2 == 7) + else if (param[i] == 7) { enable_reverse(vgabuf); } - else if (vgabuf->param2 == 8) + else if (param[i] == 8) { enable_hide(vgabuf); } - else if (vgabuf->param2 == 25) - { - disable_blink(); - vgabuf->color &= (~FLASH_CHAR); - } - else if (vgabuf->param2 == 27) + else if (param[i] == 27) { disable_reverse(vgabuf); } - else if (vgabuf->param2 == 28) + else if (param[i] == 28) { disable_hide(vgabuf); } - else if (30 <= vgabuf->param2 && vgabuf->param2 <= 37) + else if (30 <= param[i] && param[i] <= 37) { - vgabuf->param2 -= 30; - param12vga_color(&(vgabuf->param2)); - vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(vgabuf->param2); + param[i] -= 30; + param12vga_color(&(param[i])); + vgabuf->color = (vgabuf->color & 0xf8ff) | FOREGROUND(param[i]); } - else if (vgabuf->param2 == 39) + else if (param[i] == 39) { u16 default_foreground = DEFAULT_CHAR_COLOR & 0x0f00; vgabuf->color = (vgabuf->color & 0xf0ff) | default_foreground; } - else if (40 <= vgabuf->param2 && vgabuf->param2 <= 47) + else if (40 <= param[i] && param[i] <= 47) { - vgabuf->param2 -= 40; - param12vga_color(&(vgabuf->param2)); - vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(vgabuf->param2); + param[i] -= 40; + param12vga_color(&(param[i])); + vgabuf->color = (vgabuf->color & 0x8fff) | BACKGROUND(param[i]); } - else if (vgabuf->param2 == 49) + else if (param[i] == 49) { u16 default_background = DEFAULT_CHAR_COLOR & 0xf000; vgabuf->color = (vgabuf->color & 0x0fff) | default_background; } - else if (90 <= vgabuf->param2 && vgabuf->param2 <= 97) + else if (90 <= param[i] && param[i] <= 97) { - vgabuf->param2 -= 90; - param12vga_color(&(vgabuf->param2)); - vgabuf->param2 |= 0x8; - vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(vgabuf->param2); + param[i] -= 90; + param12vga_color(&(param[i])); + param[i] |= 0x8; + vgabuf->color = (vgabuf->color & 0xf0ff) | FOREGROUND(param[i]); } - else if (100 <= vgabuf->param2 && vgabuf->param2 <= 107) + else if (100 <= param[i] && param[i] <= 107) { - vgabuf->param2 -= 100; - param12vga_color(&(vgabuf->param2)); - vgabuf->param2 |= 0x8; - vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(vgabuf->param2); + param[i] -= 100; + param12vga_color(&(param[i])); + param[i] |= 0x8; + vgabuf->color = (vgabuf->color & 0x0fff) | BACKGROUND(param[i]); } else { - warn("\x1b[47;93unsupport CSI: sgr param:%d\n", vgabuf->param2); + warn("\x1b[47;93munsupport CSI: sgr param[%d]:%d\x1b[m\n", i, param[i]); } } } @@ -405,88 +328,103 @@ void CSI_Erase_handler(vga_buf *vgabuf, int n) void CSI_handler(u8 terminator, vga_buf *vgabuf) { vgabuf->CSI = CSI_ESC; + i16 param[MAXNUM_PARAM] = {0}; + i16 param_cnt = 0; + for (int i = 0; i < vgabuf->param_num && param_cnt < MAXNUM_PARAM; i++) + { + u8 ch = vgabuf->param_c[i]; + if (ch != ';') + { + param[param_cnt] = param[param_cnt] * 10 + ch - '0'; + } + else + { + param_cnt++; + continue; + } + } switch (terminator) { case 'A': // Cursor Up - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - cursor_move(-vgabuf->param1, 0, vgabuf); + if (param[0] == 0) + param[0] = 1; + cursor_move(-param[0], 0, vgabuf); break; case 'B': // Cursor Down - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - cursor_move(+vgabuf->param1, 0, vgabuf); + if (param[0] == 0) + param[0] = 1; + cursor_move(+param[0], 0, vgabuf); break; case 'C': // Cursor Forward - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - cursor_move(0, +vgabuf->param1, vgabuf); + if (param[0] == 0) + param[0] = 1; + cursor_move(0, +param[0], vgabuf); break; case 'D': // Cursor Back - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - cursor_move(0, -vgabuf->param1, vgabuf); // nothing + if (param[0] == 0) + param[0] = 1; + cursor_move(0, -param[0], vgabuf); // nothing break; case 'E': // Cursor Next Line - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - cursor_move(+vgabuf->param1, -vgabuf->cur_col, vgabuf); + if (param[0] == 0) + param[0] = 1; + cursor_move(+param[0], -vgabuf->cur_col, vgabuf); break; case 'F': // Cursor Previous Line - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - cursor_move(-vgabuf->param1, -vgabuf->cur_col, vgabuf); + if (param[0] == 0) + param[0] = 1; + cursor_move(-param[0], -vgabuf->cur_col, vgabuf); break; case 'G': // Cursor Horizontal Absolute - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - cursor_locate(CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE), vgabuf->param1 - 1, vgabuf); + if (param[0] == 0) + param[0] = 1; + cursor_locate(CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE), param[0] - 1, vgabuf); break; case 'H': // Cursor Position case 'f': - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - if (vgabuf->param2 == 0) - vgabuf->param2 = 1; - cursor_locate(vgabuf->param1 - 1, vgabuf->param2 - 1, vgabuf); + if (param[0] == 0) + param[0] = 1; + if (param[1] == 0) + param[1] = 1; + cursor_locate(param[0] - 1, param[1] - 1, vgabuf); break; case 'J': // Erase in Display - if (vgabuf->param1 == 0) + if (param[0] == 0) // from Cursor Position to the end of the screen clear_screen(vgabuf, vgabuf->scr_cur_line, vgabuf->cur_col, ADDLINE(vgabuf->scr_top_line, SCR_HEIGHT - 1), SCR_WIDTH - 1); - else if (vgabuf->param1 == 1) + else if (param[0] == 1) // from Cursor Position to the start of the screen clear_screen(vgabuf, vgabuf->scr_top_line, 0, vgabuf->scr_cur_line, vgabuf->cur_col); - else if (vgabuf->param1 == 2) + else if (param[0] == 2) // The whole screen CSI_Erase_handler(vgabuf, 2); - else if (vgabuf->param1 == 3) + else if (param[0] == 3) // The whole screen and the buffer CSI_Erase_handler(vgabuf, 3); break; case 'K': // Erase in Line - if (vgabuf->param1 == 0) + if (param[0] == 0) // from Cursor Position to the end of the line clear_screen(vgabuf, vgabuf->scr_cur_line, vgabuf->cur_col, vgabuf->scr_cur_line, SCR_WIDTH - 1); - else if (vgabuf->param1 == 1) + else if (param[0] == 1) // from Cursor Position to the start of the line clear_screen(vgabuf, vgabuf->scr_cur_line, 0, vgabuf->scr_cur_line, vgabuf->cur_col); - else if (vgabuf->param1 == 2) + else if (param[0] == 2) // The whole line clear_screen(vgabuf, vgabuf->scr_cur_line, 0, vgabuf->scr_cur_line, SCR_WIDTH - 1); break; case 'S': // Scroll Up - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - csi_scroll(vgabuf, -vgabuf->param1); + if (param[0] == 0) + param[0] = 1; + csi_scroll(vgabuf, -param[0]); break; case 'T': // Scroll Down - if (vgabuf->param1 == 0) - vgabuf->param1 = 1; - csi_scroll(vgabuf, +vgabuf->param1); + if (param[0] == 0) + param[0] = 1; + csi_scroll(vgabuf, +param[0]); break; case 'm': // Select Graphic Rendition - set_color(vgabuf); + set_color(param_cnt, param, vgabuf); break; } } \ No newline at end of file diff --git a/kernel/vga.c b/kernel/vga.c index b8267ca..a850280 100644 --- a/kernel/vga.c +++ b/kernel/vga.c @@ -133,10 +133,10 @@ void vga_tty_init(NTTY *tty) // buf->max_line = SCR_BUFSIZE / SCR_WIDTH; vga->scr_top_line = vga->scr_cur_line = vga->scr_bot_line = 0; vga->head_line = 0; - vga->Is2param = false; vga->IsColorReverse = false; vga->IsHide = false; vga->color = DEFAULT_CHAR_COLOR; + vga->CSI = CSI_ESC; u32 *ptr_buf = (u32 *)vga->buf; for (int i = 0; i < SCR_BUFSIZE * sizeof(u16) / sizeof(u32); ++i) { @@ -217,7 +217,6 @@ void vga_tty_write(NTTY *tty, char ch) break; case '\x1b': vga->CSI = CSI_BRACKET; - vga->Is2param = false; break; default: buf[INDEX(vga->scr_cur_line, vga->cur_col)] = MAKE_CELL(vga->color, ch); @@ -231,8 +230,13 @@ void vga_tty_write(NTTY *tty, char ch) switch (ch) { case '[': - vga->CSI = CSI_PARAM1; - vga->param1 = vga->param2 = 0; + vga->CSI = CSI_PARAM; + // init + for (int i = 0; i < MAXNUM_PARAM_CH; i++) + { + vga->param_c[i] = 0; + } + vga->param_num = 0; break; default: vga->CSI = CSI_ESC; @@ -253,18 +257,11 @@ void vga_tty_write(NTTY *tty, char ch) case '7': case '8': case '9': - if (vga->CSI == CSI_PARAM1) - vga->param1 = vga->param1 * 10 + ch - '0'; - else if (vga->CSI == CSI_PARAM2) - vga->param2 = vga->param2 * 10 + ch - '0'; - else - ; // do nothing - break; case ';': - if (vga->CSI == CSI_PARAM1) + if (vga->param_num < MAXNUM_PARAM_CH) { - vga->CSI = CSI_PARAM2; - vga->Is2param = true; + vga->param_c[vga->param_num] = ch; + vga->param_num++; } break; default: