📄 console.c
字号:
else if (!nr)
nr = 1;
while (nr--)
insert_line();
}
static void csi_P(unsigned int nr)
{
if (nr > VIDEO_NUM_COLUMNS)
nr = VIDEO_NUM_COLUMNS;
else if (!nr)
nr = 1;
while (nr--)
delete_char();
}
static void csi_M(unsigned int nr)
{
if (nr > video_num_lines)
nr = video_num_lines;
else if (!nr)
nr=1;
while (nr--)
delete_line();
}
//新行
static void newline()
{
if (y + 1 < bottom) {
++y;
pos += video_size_row;
} else {
screen_up(top, bottom);
}
}
//回车
static inline void enter()
{
pos -= x << 1;
x = 0;
}
//光标上已一行
static void reverse_line_feed(void)
{
if (y > top) {
y--;
pos -= video_size_row;
return;
} else {
screen_down();
}
}
//删除光标前一字符
static inline void del(int currcons)
{
if (x) {
pos -= 2;
x--;
*(unsigned short *)pos = video_erase_char;
need_wrap = 0;
}
}
static void respond(int currcons, struct tty_struct * tty)
{
char * p = RESPONSE;
cli();
while (*p) {
PUTCH(*p, tty->read_q);
p++;
}
sti();
copy_to_cooked(tty);
}
enum {
ESnormal,
ESesc,
ESsquare,
ESgetpars,
ESgotpars,
ESfunckey,
ESsetterm,
ESsetgraph,
ESgraph,
ESgresc,
ESignore
};
static int saved_x=0;
static int saved_y=0;
static void save_cur(void)
{
saved_x = x;
saved_y = y;
}
static void restore_cur(void)
{
goto_xy(saved_x, saved_y);
}
void con_write(struct tty_struct * tty)
{
int currcons = 0;
int nr;
char c;
nr = CHARS(tty->write_q);
while (nr--) {
GETCH(tty->write_q, c);
////0:初始状态,或者原是状态4,或者原是状态1,但字符不是'['
////1:原是状态0,并且字符是转义字符ESC(0X1B)
////2:原是状态1,并且字符是'['
////3:原是状态2,或者原是状态3,并且字符是;或数字
////4:原是状态3,并且字符不是';'或数字
switch(state) {
case 0:
//printk("|state==0|");
if (c > 31 && c < 127) {//不是控制字符和扩展字符
if (x >= VIDEO_NUM_COLUMNS) {
x -= VIDEO_NUM_COLUMNS;
pos -= video_size_row;
newline();
}
__asm__("movb _attr, %%ah\n\t"
"movw %%ax, %1\n\t"
::"a" (c),"m" (*(short *)pos)
);
pos += 2;
x++;
} else if (c == 27) { //如果是转义符号
state = 1;
} else if (c == 10 || c == 11 || c == 12) { //如果是换行符,垂直制表符,换页符
newline();
} else if (c == 13) { //如果是回车符
enter();
} else if (c == ERASE_CHAR(tty)) { //如果是DEL,
del(currcons);
} else if (c == 8) {
if (x) {
x--;
pos -= 2;
}
} else if (c == 9) { //如果是TAB
c = 8 - (x & 7);
x += c;
pos += c << 1;
if (x > VIDEO_NUM_COLUMNS) {
x -= VIDEO_NUM_COLUMNS;
pos -= video_size_row;
newline();
}
c=9;
} else if (c == 7) { //响铃符
sysbeep();
}
break;
case 1:
//printk("|state==1|");
state = 0;
if (c == '[') { //如果是'[',将状态转到2
state = 2;
} else if (c == 'E') {
goto_xy(currcons, y + 1); //光标移到下一行开始处
} else if (c == 'M') {
reverse_line_feed(); //光标上移一行
} else if (c == 'D') {
newline();
} else if (c == 'Z') { //向终端发送应答字符序列
respond(currcons, tty);
} else if (c == '7') {
save_cur(); //保存光标位置
} else if (c == '8') {
restore_cur(); //恢复光标位置
}
break;
case 2:
//printk("|state==2|");
for (npar = 0; npar < NPAR; npar++) {
par[npar] = 0;
}
npar = 0;
state = 3;
if (ques = (c == '?')) {
break;
}
case 3:
//printk("|state==3|");
if (c == ';' && npar < NPAR - 1) {
npar++;
break;
} else if (c >= '0' && c <= '9') {
par[npar] = 10 * par[npar] + c - '0';
break;
} else {
state=4;
}
case 4:
//printk("|state==4|");
state = 0;
switch(c) {
case 'G':
case '`':
if (par[0]) {
par[0]--;
}
goto_xy(par[0], y);
break;
case 'A':
if (!par[0]) {
par[0]++;
}
goto_xy(x, y - par[0]);
break;
case 'B':
case 'e':
if (!par[0]) {
par[0]++;
}
goto_xy(x, y + par[0]);
break;
case 'C':
case 'a':
if (!par[0]) {
par[0]++;
}
goto_xy(x + par[0], y);
break;
case 'D':
if (!par[0]) {
par[0]++;
}
goto_xy(x - par[0],y);
break;
case 'E':
if (!par[0]) {
par[0]++;
}
goto_xy(0, y + par[0]);
break;
case 'F':
if (!par[0]) {
par[0]++;
}
goto_xy(0, y - par[0]);
break;
case 'd':
if (par[0]) {
par[0]--;
}
goto_xy(x, par[0]);
break;
case 'H':
case 'f':
if (par[0]) {
par[0]--;
}
if (par[1]) {
par[1]--;
}
goto_xy(par[1], par[0]);
break;
case 'J':
csi_J(par[0]);
break;
case 'K':
csi_K(par[0]);
break;
case 'L':
csi_L(par[0]);
break;
case 'M':
csi_M(par[0]);
break;
case 'P':
csi_P(par[0]);
break;
case '@':
csi_at(par[0]);
break;
case 'm':
csi_m();
break;
case 'r':
if (par[0]) {
par[0]--;
}
if (!par[1]) {
par[1] = video_num_lines;
}
if (par[0] < par[1] &&
par[1] <= video_num_lines) {
top = par[0];
bottom = par[1];
}
break;
case 's':
save_cur();
break;
case 'u':
restore_cur();
break;
}
}
}
set_cursor();
}
static void sysbeep(void)
{
/*
// enable counter 2
outb_p(inb_p(0x61)|3, 0x61);
// set command for counter 2, 2 byte write
outb_p(0xB6, 0x43);
// send 0x637 for 750 HZ
outb_p(0x37, 0x42); outb(0x06, 0x42);
// 1/8 second
timer_table[BEEP_TIMER].expires = jiffies + HZ/8;
timer_table[BEEP_TIMER].fn = sysbeepstop;
timer_active |= 1<<BEEP_TIMER;
*/
}
//直接在显示内存显示字符串
void console_print(const char *str)
{
char c;
while (c = *(str++)) {
if (c == 10 || c == 13) {
if (c == 10) {
newline();
}
enter();
} else {
*(char *) pos = c;
*(char *) (pos + 1) = ATTR;
if (x == VIDEO_NUM_COLUMNS - 1) {
newline();
enter();
} else {
x++;
pos += 2;
}
}
}
set_cursor();
}
//初始化控制台
void con_init()
{
int currcons = 0;
u16 *pmemchar;
//暂时设置显示内存地址,现在比较笨,写死了,以后在根据显卡类型判断吧
video_mem_base = 0xC00B8000;
video_mem_term = 0xC00BDDC0;
video_mem_start = video_mem_base;
video_mem_end = video_mem_term;
origin = video_mem_base;
pos = origin;
video_size_row = VIDEO_NUM_COLUMNS * 2;
bottom = video_num_lines;
screen_end = video_mem_start + video_size_row * video_num_lines;
video_erase_char = (7 << 8) | ' ';
//for (currcons = 0; currcons < NR_CONSOLES; currcons++) {
// reset_terminal(currcons, currcons);
//}
goto_xy(0, 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -