📄 console.c
字号:
tab_stop[4] = 0x01010101;
if (do_clear) {
gotoxy(currcons,0,0);
csi_J(currcons,2);
save_cur(currcons);
}
}
void con_write(struct tty_struct * tty)
{
int c;
unsigned int currcons;
currcons = tty->line - 1;
if (currcons >= NR_CONSOLES) {
printk("con_write: illegal tty (%d)\n", currcons);
return;
}
#ifdef CONFIG_SELECTION
/* clear the selection as soon as any characters are to be written
out on the console holding the selection. */
if (!EMPTY(&tty->write_q) && currcons == sel_cons)
clear_selection();
#endif /* CONFIG_SELECTION */
disable_bh(KEYBOARD_BH);
while (!tty->stopped && (c = get_tty_queue(&tty->write_q)) >= 0) {
if (state == ESnormal && translate[c]) {
if (need_wrap) {
cr(currcons);
lf(currcons);
}
if (decim)
insert_char(currcons);
c = translate[c];
*(unsigned short *) pos = (attr << 8) + c;
if (x == video_num_columns - 1)
need_wrap = decawm;
else {
x++;
pos+=2;
}
continue;
}
/*
* Control characters can be used in the _middle_
* of an escape sequence.
*/
switch (c) {
case 7:
kd_mksound(0x637, HZ/8);
continue;
case 8:
bs(currcons);
continue;
case 9:
pos -= (x << 1);
while (x < video_num_columns - 1) {
x++;
if (tab_stop[x >> 5] & (1 << (x & 31)))
break;
}
pos += (x << 1);
continue;
case 10: case 11: case 12:
lf(currcons);
if (!is_kbd(lnm))
continue;
case 13:
cr(currcons);
continue;
case 14:
charset = 1;
translate = G1_charset;
continue;
case 15:
charset = 0;
translate = G0_charset;
continue;
case 24: case 26:
state = ESnormal;
continue;
case 27:
state = ESesc;
continue;
case 127:
del(currcons);
continue;
case 128+27:
state = ESsquare;
continue;
}
switch(state) {
case ESesc:
state = ESnormal;
switch (c) {
case '[':
state = ESsquare;
continue;
case 'E':
cr(currcons);
lf(currcons);
continue;
case 'M':
ri(currcons);
continue;
case 'D':
lf(currcons);
continue;
case 'H':
tab_stop[x >> 5] |= (1 << (x & 31));
continue;
case 'Z':
respond_ID(currcons,tty);
continue;
case '7':
save_cur(currcons);
continue;
case '8':
restore_cur(currcons);
continue;
case '(':
state = ESsetG0;
continue;
case ')':
state = ESsetG1;
continue;
case '#':
state = EShash;
continue;
case 'c':
reset_terminal(currcons,1);
continue;
case '>': /* Numeric keypad */
clr_kbd(kbdapplic);
continue;
case '=': /* Appl. keypad */
set_kbd(kbdapplic);
continue;
}
continue;
case ESsquare:
for(npar = 0 ; npar < NPAR ; npar++)
par[npar] = 0;
npar = 0;
state = ESgetpars;
if (c == '[') { /* Function key */
state=ESfunckey;
continue;
}
ques = (c=='?');
if (ques)
continue;
case ESgetpars:
if (c==';' && npar<NPAR-1) {
npar++;
continue;
} else if (c>='0' && c<='9') {
par[npar] *= 10;
par[npar] += c-'0';
continue;
} else state=ESgotpars;
case ESgotpars:
state = ESnormal;
switch(c) {
case 'h':
set_mode(currcons,1);
continue;
case 'l':
set_mode(currcons,0);
continue;
case 'n':
if (!ques)
if (par[0] == 5)
status_report(currcons,tty);
else if (par[0] == 6)
cursor_report(currcons,tty);
continue;
}
if (ques) {
ques = 0;
continue;
}
switch(c) {
case 'G': case '`':
if (par[0]) par[0]--;
gotoxy(currcons,par[0],y);
continue;
case 'A':
if (!par[0]) par[0]++;
gotoxy(currcons,x,y-par[0]);
continue;
case 'B': case 'e':
if (!par[0]) par[0]++;
gotoxy(currcons,x,y+par[0]);
continue;
case 'C': case 'a':
if (!par[0]) par[0]++;
gotoxy(currcons,x+par[0],y);
continue;
case 'D':
if (!par[0]) par[0]++;
gotoxy(currcons,x-par[0],y);
continue;
case 'E':
if (!par[0]) par[0]++;
gotoxy(currcons,0,y+par[0]);
continue;
case 'F':
if (!par[0]) par[0]++;
gotoxy(currcons,0,y-par[0]);
continue;
case 'd':
if (par[0]) par[0]--;
gotoxy(currcons,x,par[0]);
continue;
case 'H': case 'f':
if (par[0]) par[0]--;
if (par[1]) par[1]--;
gotoxy(currcons,par[1],par[0]);
continue;
case 'J':
csi_J(currcons,par[0]);
continue;
case 'K':
csi_K(currcons,par[0]);
continue;
case 'L':
csi_L(currcons,par[0]);
continue;
case 'M':
csi_M(currcons,par[0]);
continue;
case 'P':
csi_P(currcons,par[0]);
continue;
case 'c':
if (!par[0])
respond_ID(currcons,tty);
continue;
case 'g':
if (!par[0])
tab_stop[x >> 5] &= ~(1 << (x & 31));
else if (par[0] == 3) {
tab_stop[0] =
tab_stop[1] =
tab_stop[2] =
tab_stop[3] =
tab_stop[4] = 0;
}
continue;
case 'm':
csi_m(currcons);
continue;
case 'r':
if (!par[0])
par[0]++;
if (!par[1])
par[1] = video_num_lines;
/* Minimum allowed region is 2 lines */
if (par[0] < par[1] &&
par[1] <= video_num_lines) {
top=par[0]-1;
bottom=par[1];
gotoxy(currcons,0,0);
}
continue;
case 's':
save_cur(currcons);
continue;
case 'u':
restore_cur(currcons);
continue;
case '@':
csi_at(currcons,par[0]);
continue;
case ']': /* setterm functions */
setterm_command(currcons);
continue;
}
continue;
case ESfunckey:
state = ESnormal;
continue;
case EShash:
state = ESnormal;
if (c == '8') {
/* DEC screen alignment test. kludge :-) */
video_erase_char =
(video_erase_char & 0xff00) | 'E';
csi_J(currcons, 2);
video_erase_char =
(video_erase_char & 0xff00) | ' ';
}
continue;
case ESsetG0:
if (c == '0')
G0_charset = GRAF_TRANS;
else if (c == 'B')
G0_charset = NORM_TRANS;
else if (c == 'U')
G0_charset = NULL_TRANS;
else if (c == 'K')
G0_charset = USER_TRANS;
if (charset == 0)
translate = G0_charset;
state = ESnormal;
continue;
case ESsetG1:
if (c == '0')
G1_charset = GRAF_TRANS;
else if (c == 'B')
G1_charset = NORM_TRANS;
else if (c == 'U')
G1_charset = NULL_TRANS;
else if (c == 'K')
G1_charset = USER_TRANS;
if (charset == 1)
translate = G1_charset;
state = ESnormal;
continue;
default:
state = ESnormal;
}
}
if (vcmode != KD_GRAPHICS)
set_cursor(currcons);
enable_bh(KEYBOARD_BH);
if (LEFT(&tty->write_q) > WAKEUP_CHARS)
wake_up_interruptible(&tty->write_q.proc_list);
}
void do_keyboard_interrupt(void)
{
TTY_READ_FLUSH(TTY_TABLE(0));
timer_active &= ~(1<<BLANK_TIMER);
if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
return;
if (console_blanked) {
timer_table[BLANK_TIMER].expires = 0;
timer_active |= 1<<BLANK_TIMER;
} else if (blankinterval) {
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
timer_active |= 1<<BLANK_TIMER;
}
}
void * memsetw(void * s,unsigned short c,int count)
{
__asm__("cld\n\t"
"rep\n\t"
"stosw"
: /* no output */
:"a" (c),"D" (s),"c" (count)
:"cx","di");
return s;
}
void console_print(const char * b)
{
int currcons = fg_console;
unsigned char c;
if (!printable || currcons<0 || currcons>=NR_CONSOLES)
return;
while ((c = *(b++)) != 0) {
if (c == 10 || c == 13 || need_wrap) {
if (c != 13)
lf(currcons);
cr(currcons);
if (c == 10 || c == 13)
continue;
}
*(unsigned short *) pos = (attr << 8) + c;
if (x == video_num_columns - 1) {
need_wrap = 1;
continue;
}
x++;
pos+=2;
}
set_cursor(currcons);
if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
return;
timer_active &= ~(1<<BLANK_TIMER);
if (console_blanked) {
timer_table[BLANK_TIMER].expires = 0;
timer_active |= 1<<BLANK_TIMER;
} else if (blankinterval) {
timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
timer_active |= 1<<BLANK_TIMER;
}
}
/*
* long con_init(long);
*
* This routine initalizes console interrupts, and does nothing
* else. If you want the screen to clear, call tty_write with
* the appropriate escape-sequece.
*
* Reads the information preserved by setup.s to determine the current display
* type and sets everything accordingly.
*/
long con_init(long kmem_start)
{
char *display_desc = "????";
int currcons = 0;
long base;
int orig_x = ORIG_X;
int orig_y = ORIG_Y;
vc_scrmembuf = (unsigned short *) kmem_start;
video_num_columns = ORIG_VIDEO_COLS;
video_size_row = video_num_columns * 2;
video_num_lines = ORIG_VIDEO_LINES;
video_page = ORIG_VIDEO_PAGE;
screen_size = (video_num_lines * video_size_row);
kmem_start += NR_CONSOLES * screen_size;
timer_table[BLANK_TIMER].fn = blank_screen;
timer_table[BLANK_TIMER].expires = 0;
if (blankinterval) {
timer_table[BLANK_TIMER].expires = jiffies+blankinterval;
timer_active |= 1<<BLANK_TIMER;
}
if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */
{
video_mem_base = 0xb0000;
video_port_reg = 0x3b4;
video_port_val = 0x3b5;
if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
{
video_type = VIDEO_TYPE_EGAM;
video_mem_term = 0xb8000;
display_desc = "EGA+";
}
else
{
video_type = VIDEO_TYPE_MDA;
video_mem_term = 0xb2000;
display_desc = "*MDA";
}
}
else /* If not, it is color. */
{
can_do_color = 1;
video_mem_base = 0xb8000;
video_port_reg = 0x3d4;
video_port_val = 0x3d5;
if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
{
video_type = VIDEO_TYPE_EGAC;
video_mem_term = 0xc0000;
display_desc = "EGA+";
}
else
{
video_type = VIDEO_TYPE_CGA;
video_mem_term = 0xba000;
display_desc = "*CGA";
}
}
/* Initialize the variables used for scrolling (mostly EGA/VGA) */
base = (long)vc_scrmembuf;
for (currcons = 0; currcons<NR_CONSOLES; currcons++) {
pos = origin = video_mem_start = base;
scr_end = video_mem_end = (base += screen_size);
vc_scrbuf[currcons] = (unsigned short *) origin;
vcmode = KD_TEXT;
vtmode.mode = VT_AUTO;
vtmode.waitv = 0;
vtmode.relsig = 0;
vtmode.acqsig = 0;
vtmode.frsig = 0;
vtpid = -1;
vtnewvt = -1;
clr_kbd(kbdraw);
def_color = 0x07; /* white */
ulcolor = 0x0f; /* bold white */
halfcolor = 0x08; /* grey */
reset_terminal(currcons, currcons);
}
currcons = fg_console = 0;
video_mem_start = video_mem_base;
video_mem_end = video_mem_term;
origin = video_mem_start;
scr_end = video_mem_start + video_num_lines * video_size_row;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -