2 * linux/drivers/char/console.c 4 * Copyright (C) 1991, 1992 Linus Torvalds 9 * This module exports the console io functions: 11 * 'void do_keyboard_interrupt(void)' 13 * 'int vc_allocate(unsigned int console)' 14 * 'int vc_cons_allocated(unsigned int console)' 15 * 'int vc_resize(unsigned long lines, unsigned long cols)' 16 * 'void vc_disallocate(unsigned int currcons)' 18 * 'unsigned long con_init(unsigned long)' 19 * 'int con_open(struct tty_struct *tty, struct file * filp)' 20 * 'void con_write(struct tty_struct * tty)' 21 * 'void vt_console_print(const char * b)' 22 * 'void update_screen(int new_console)' 24 * 'void do_blank_screen(int)' 25 * 'void do_unblank_screen(void)' 26 * 'void poke_blanked_console(void)' 28 * 'unsigned short *screen_pos(int currcons, int w_offset, int viewed)' 29 * 'void complement_pos(int currcons, int offset)' 30 * 'void invert_screen(int currcons, int offset, int count, int shift)' 32 * 'void scrollback(int lines)' 33 * 'void scrollfront(int lines)' 35 * 'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)' 36 * 'int mouse_reporting(void)' 38 * Hopefully this will be a rather complete VT102 implementation. 40 * Beeping thanks to John T Kohl. 42 * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics 43 * Chars, and VT100 enhancements by Peter MacDonald. 45 * Copy and paste function by Andrew Haylett, 46 * some enhancements by Alessandro Rubini. 48 * Code to check for different video-cards mostly by Galen Hunt, 49 * <g-hunt@ee.utah.edu> 51 * Rudimentary ISO 10646/Unicode/UTF-8 character set support by 52 * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>. 54 * Dynamic allocation of consoles, aeb@cwi.nl, May 1994 55 * Resizing of consoles, aeb, 940926 57 * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94 60 * User-defined bell sound, new setterm control sequences and printk 61 * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95 63 * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp> 68 /* A bitmap for codes <32. A bit of 1 indicates that the code 69 * corresponding to that bit number invokes some special action 70 * (such as cursor movement) and should not be displayed as a 71 * glyph unless the disp_ctrl mode is explicitly enabled. 73 #define CTRL_ACTION 0x0d00ff81 74 #define CTRL_ALWAYS 0x0800f501/* Cannot be overridden by disp_ctrl */ 77 * Here is the default bell parameters: 750HZ, 1/8th of a second 79 #define DEFAULT_BELL_PITCH 750 80 #define DEFAULT_BELL_DURATION (HZ/8) 83 * NOTE!!! We sometimes disable and enable interrupts for a short while 84 * (to put a word in video IO), but this will work even for keyboard 85 * interrupts. We know interrupts aren't enabled when getting a keyboard 86 * interrupt, as we use trap-gates. Hopefully all is well. 89 #include <linux/sched.h> 90 #include <linux/timer.h> 91 #include <linux/interrupt.h> 92 #include <linux/tty.h> 93 #include <linux/tty_flip.h> 94 #include <linux/console.h> 95 #include <linux/config.h> 96 #include <linux/kernel.h> 97 #include <linux/string.h> 98 #include <linux/errno.h> 100 #include <linux/malloc.h> 101 #include <linux/major.h> 102 #include <linux/mm.h> 103 #include <linux/ioport.h> 104 #include <linux/init.h> 106 #include <linux/apm_bios.h> 110 #include <asm/system.h> 111 #include <asm/uaccess.h> 112 #include <asm/bitops.h> 114 #include <linux/kbd_kern.h> 115 #include <linux/vt_kern.h> 116 #include <linux/consolemap.h> 117 #include <linux/selection.h> 118 #include <linux/console_struct.h> 121 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 128 struct tty_driver console_driver
; 129 static int console_refcount
; 130 static struct tty_struct
*console_table
[MAX_NR_CONSOLES
]; 131 static struct termios
*console_termios
[MAX_NR_CONSOLES
]; 132 static struct termios
*console_termios_locked
[MAX_NR_CONSOLES
]; 133 unsigned short*vc_scrbuf
[MAX_NR_CONSOLES
]; 134 struct vc vc_cons
[MAX_NR_CONSOLES
]; 136 static intcon_open(struct tty_struct
*,struct file
*); 137 static voidcon_setsize(unsigned long rows
,unsigned long cols
); 138 static voidvc_init(unsigned int console
,unsigned long rows
, 139 unsigned long cols
,int do_clear
); 140 externvoidget_scrmem(int currcons
); 141 externvoidset_scrmem(int currcons
,long offset
); 142 static voidset_origin(int currcons
); 143 static voidblank_screen(void); 144 static voidunblank_screen(void); 145 externvoidchange_console(unsigned int); 146 externvoidpoke_blanked_console(void); 147 static voidgotoxy(int currcons
,int new_x
,int new_y
); 148 static voidsave_cur(int currcons
); 149 externvoidset_cursor(int currcons
); 150 externvoidhide_cursor(void); 151 static voidreset_terminal(int currcons
,int do_clear
); 152 externvoidreset_vc(unsigned int new_console
); 153 externvoidvt_init(void); 154 externvoidset_vesa_blanking(unsigned long arg
); 155 externvoidvesa_blank(void); 156 externvoidvesa_unblank(void); 157 externvoidvesa_powerdown(void); 158 externvoidcompute_shiftstate(void); 159 externvoidreset_palette(int currcons
); 160 externvoidset_palette(void); 161 externintcon_is_present(void); 162 externunsigned longcon_type_init(unsigned long,const char**); 163 externvoidcon_type_init_finish(void); 164 externintset_get_cmap(unsigned char*,int); 165 externintset_get_font(unsigned char*,int,int); 166 externvoidrs_cons_hook(int chip
,int out
,int channel
); 168 /* Description of the hardware situation */ 169 unsigned char video_type
;/* Type of display being used */ 170 unsigned long video_mem_base
;/* Base of video memory */ 171 unsigned long video_mem_term
;/* End of video memory */ 172 unsigned short video_port_reg
;/* Video register select port */ 173 unsigned short video_port_val
;/* Video register value port */ 174 unsigned long video_num_columns
;/* Number of text columns */ 175 unsigned long video_num_lines
;/* Number of text lines */ 176 unsigned long video_size_row
; 177 unsigned long video_screen_size
; 180 static int printable
=0;/* Is console ready for printing? */ 182 int video_mode_512ch
=0;/* 512-character mode */ 183 unsigned long video_font_height
;/* Height of current screen font */ 184 unsigned long video_scan_lines
;/* Number of scan lines on screen */ 185 static unsigned long default_font_height
;/* Height of default screen font */ 186 int video_font_is_default
=1; 187 static unsigned short console_charmask
=0x0ff; 189 /* used by kbd_bh - set by keyboard_interrupt */ 190 int do_poke_blanked_console
=0; 191 int console_blanked
=0; 192 static int blankinterval
=10*60*HZ
; 193 static int vesa_off_interval
=0; 194 static long blank_origin
, blank__origin
, unblank_origin
; 197 * fg_console is the current virtual console, 198 * last_console is the last used one, 199 * want_console is the console we want to switch to, 200 * kmsg_redirect is the console for kernel messages, 204 int want_console
= -1; 205 int kmsg_redirect
=0; 207 #define CONFIG_SERIAL_ECHO 208 #ifdef CONFIG_SERIAL_ECHO 210 #include <linux/serial_reg.h> 212 externintserial_echo_init(int base
); 213 externintserial_echo_print(const char*s
); 216 * this defines the address for the port to which printk echoing is done 217 * when CONFIG_SERIAL_ECHO is defined 219 #define SERIAL_ECHO_PORT 0x3f8/* COM1 */ 221 static int serial_echo_port
=0; 223 #define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port) 224 #define serial_echo_inb(a) inb((a)+serial_echo_port) 226 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) 228 /* Wait for transmitter & holding register to empty */ 229 #define WAIT_FOR_XMITR \ 231 lsr = serial_echo_inb(UART_LSR); \ 232 } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY) 234 /* These two functions abstract the actual communications with the 235 * debug port. This is so we can change the underlying communications 236 * mechanism without modifying the rest of the code. 239 serial_echo_print(const char*s
) 244 if(!serial_echo_port
)return(0); 247 * First save the IER then disable the interrupts 249 ier
=serial_echo_inb(UART_IER
); 250 serial_echo_outb(0x00, UART_IER
); 253 * Now, do each character 255 for(i
=0; *s
; i
++, s
++) { 258 /* Send the character out. */ 259 serial_echo_outb(*s
, UART_TX
); 261 /* if a LF, also do CR... */ 264 serial_echo_outb(13, UART_TX
); 269 * Finally, Wait for transmitter & holding register to empty 270 * and restore the IER 273 lsr
=serial_echo_inb(UART_LSR
); 274 }while((lsr
& BOTH_EMPTY
) != BOTH_EMPTY
); 275 serial_echo_outb(ier
, UART_IER
); 282 serial_echo_init(int base
) 286 if(base
!=0x2f8&& base
!=0x3f8) { 290 serial_echo_port
= base
; 293 * read the Divisor Latch 295 comstat
=serial_echo_inb(UART_LCR
); 296 serial_echo_outb(comstat
| UART_LCR_DLAB
, UART_LCR
); 297 hi
=serial_echo_inb(UART_DLM
); 298 lo
=serial_echo_inb(UART_DLL
); 299 serial_echo_outb(comstat
, UART_LCR
); 302 * now do hardwired init 304 serial_echo_outb(0x03, UART_LCR
);/* No parity, 8 data bits, 1 stop */ 305 serial_echo_outb(0x83, UART_LCR
);/* Access divisor latch */ 306 serial_echo_outb(0x00, UART_DLM
);/* 9600 baud */ 307 serial_echo_outb(0x0c, UART_DLL
); 308 serial_echo_outb(0x03, UART_LCR
);/* Done with divisor */ 310 /* Prior to disabling interrupts, read the LSR and RBR 313 comstat
=serial_echo_inb(UART_LSR
);/* COM? LSR */ 314 comstat
=serial_echo_inb(UART_RX
);/* COM? RBR */ 315 serial_echo_outb(0x00, UART_IER
);/* Disable all interrupts */ 320 #endif/* CONFIG_SERIAL_ECHO */ 322 intvc_cons_allocated(unsigned int i
) 324 return(i
< MAX_NR_CONSOLES
&& vc_cons
[i
].d
); 327 intvc_allocate(unsigned int i
)/* return 0 on success */ 329 if(i
>= MAX_NR_CONSOLES
) 334 /* prevent users from taking too much memory */ 335 if(i
>= MAX_NR_USER_CONSOLES
&& !suser()) 338 /* due to the granularity of kmalloc, we waste some memory here */ 339 /* the alloc is done in two steps, to optimize the common situation 340 of a 25x80 console (structsize=216, video_screen_size=4000) */ 341 q
= (long)kmalloc(video_screen_size
, GFP_KERNEL
); 344 p
= (long)kmalloc(structsize
, GFP_KERNEL
); 346 kfree_s((char*) q
, video_screen_size
); 350 vc_cons
[i
].d
= (struct vc_data
*) p
; 351 p
+=sizeof(struct vc_data
); 352 vt_cons
[i
] = (struct vt_struct
*) p
; 353 vc_scrbuf
[i
] = (unsigned short*) q
; 354 vc_cons
[i
].d
->vc_kmalloced
=1; 355 vc_cons
[i
].d
->vc_screenbuf_size
= video_screen_size
; 356 vc_init(i
, video_num_lines
, video_num_columns
,1); 362 * Change # of rows and columns (0 means unchanged) 363 * [this is to be used together with some user program 364 * like resize that changes the hardware videomode] 366 intvc_resize(unsigned long lines
,unsigned long cols
) 368 unsigned long cc
, ll
, ss
, sr
; 369 unsigned long occ
, oll
, oss
, osr
; 371 unsigned int currcons
, i
; 372 unsigned short*newscreens
[MAX_NR_CONSOLES
]; 373 long ol
, nl
, rlth
, rrem
; 375 cc
= (cols
? cols
: video_num_columns
); 376 ll
= (lines
? lines
: video_num_lines
); 380 if(ss
> video_mem_term
- video_mem_base
) 384 * Some earlier version had all consoles of potentially 385 * different sizes, but that was really messy. 386 * So now we only change if there is room for all consoles 389 for(currcons
=0; currcons
< MAX_NR_CONSOLES
; currcons
++) { 390 if(!vc_cons_allocated(currcons
)) 391 newscreens
[currcons
] =0; 393 p
= (unsigned short*)kmalloc(ss
, GFP_USER
); 395 for(i
=0; i
< currcons
; i
++) 397 kfree_s(newscreens
[i
], ss
); 400 newscreens
[currcons
] = p
; 404 get_scrmem(fg_console
); 406 oll
= video_num_lines
; 407 occ
= video_num_columns
; 408 osr
= video_size_row
; 409 oss
= video_screen_size
; 411 video_num_lines
= ll
; 412 video_num_columns
= cc
; 414 video_screen_size
= ss
; 416 for(currcons
=0; currcons
< MAX_NR_CONSOLES
; currcons
++) { 417 if(!vc_cons_allocated(currcons
)) 423 nl
= (long) newscreens
[currcons
]; 425 ol
+= (oll
- ll
) * osr
; 427 while(ol
< scr_end
) { 428 memcpyw((unsigned short*) nl
, (unsigned short*) ol
, rlth
); 430 memsetw((void*)(nl
+ rlth
), video_erase_char
, rrem
); 436 kfree_s(vc_scrbuf
[currcons
], screenbuf_size
); 437 vc_scrbuf
[currcons
] = newscreens
[currcons
]; 441 origin
= video_mem_start
= (long) vc_scrbuf
[currcons
]; 442 scr_end
= video_mem_end
= video_mem_start
+ ss
; 445 memsetw((void*) nl
, video_erase_char
, scr_end
- nl
); 447 /* do part of a reset_terminal() */ 449 bottom
= video_num_lines
; 450 gotoxy(currcons
, x
, y
); 454 set_scrmem(fg_console
,0); 455 set_origin(fg_console
); 456 set_cursor(fg_console
); 461 voidvc_disallocate(unsigned int currcons
) 463 if(vc_cons_allocated(currcons
)) { 465 kfree_s(vc_scrbuf
[currcons
], screenbuf_size
); 466 if(currcons
>= MIN_NR_CONSOLES
) 467 kfree_s(vc_cons
[currcons
].d
, structsize
); 468 vc_cons
[currcons
].d
=0; 473 #define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x) 474 #define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x) 475 #define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x) 477 #define decarm VC_REPEAT 478 #define decckm VC_CKMODE 479 #define kbdapplic VC_APPLIC 483 * this is what the terminal answers to a ESC-Z or csi0c query. 485 #define VT100ID"\033[?1;2c" 486 #define VT102ID"\033[?6c" 488 unsigned char color_table
[] = {0,4,2,6,1,5,3,7, 489 8,12,10,14,9,13,11,15}; 491 /* the default colour table, for VGA+ colour systems */ 492 int default_red
[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa, 493 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff}; 494 int default_grn
[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, 495 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff}; 496 int default_blu
[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, 497 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; 500 * gotoxy() must verify all boundaries, because the arguments 501 * might also be negative. If the given position is out of 502 * bounds, the cursor is placed at the nearest margin. 504 static voidgotoxy(int currcons
,int new_x
,int new_y
) 511 if(new_x
>= video_num_columns
) 512 x
= video_num_columns
-1; 520 max_y
= video_num_lines
; 524 else if(new_y
>= max_y
) 528 pos
= origin
+ y
*video_size_row
+ (x
<<1); 532 /* for absolute user moves, when decom is set */ 533 static voidgotoxay(int currcons
,int new_x
,int new_y
) 535 gotoxy(currcons
, new_x
, decom
? (top
+new_y
) : new_y
); 539 * Hardware scrollback support 541 externvoid__set_origin(unsigned short); 542 unsigned short __real_origin
;/* offset of non-scrolled screen */ 543 unsigned short __origin
;/* offset of currently displayed screen */ 544 unsigned char has_wrapped
;/* all of videomem is data of fg_console */ 545 static unsigned char hardscroll_enabled
; 546 static unsigned char hardscroll_disabled_by_init
=0; 548 voidno_scroll(char*str
,int*ints
) 551 * Disabling scrollback is required for the Braillex ib80-piezo 552 * Braille reader made by F.H. Papenmeier (Germany). 553 * Use the "no-scroll" bootflag. 555 hardscroll_disabled_by_init
=1; 556 hardscroll_enabled
=0; 559 static voidscrolldelta(int lines
) 562 int last_origin_rel
= (((video_mem_term
- video_mem_base
) 563 / video_num_columns
/2) - (video_num_lines
-1)) * video_num_columns
; 565 new_origin
= __origin
+ lines
* video_num_columns
; 566 if(__origin
> __real_origin
) 567 new_origin
-= last_origin_rel
; 569 int s_top
= __real_origin
+ video_num_lines
*video_num_columns
; 570 new_origin
+= last_origin_rel
; 571 if(new_origin
< s_top
) 573 if(new_origin
> last_origin_rel
- video_num_columns
577 unsigned short* d
= (unsigned short*) video_mem_base
; 578 unsigned short* s
= d
+ last_origin_rel
; 579 int count
= (video_num_lines
-1)*video_num_columns
; 582 scr_writew(scr_readw(d
++),s
++); 585 }else if(new_origin
> __real_origin
) 586 new_origin
= __real_origin
; 588 __set_origin(new_origin
); 591 voidscrollback(int lines
) 594 lines
= video_num_lines
/2; 598 voidscrollfront(int lines
) 601 lines
= video_num_lines
/2; 605 static voidset_origin(int currcons
) 607 if(video_type
!= VIDEO_TYPE_EGAC
&& video_type
!= VIDEO_TYPE_VGAC
608 && video_type
!= VIDEO_TYPE_EGAM
) 610 if(currcons
!= fg_console
|| console_blanked
|| vcmode
== KD_GRAPHICS
) 612 __real_origin
= (origin
-video_mem_base
) >>1; 613 __set_origin(__real_origin
); 616 static voidscrup(int currcons
,unsigned int t
,unsigned int b
,unsigned int nr
) 618 int hardscroll
= hardscroll_enabled
; 622 if(b
> video_num_lines
|| t
>= b
|| nr
<1) 624 if(t
|| b
!= video_num_lines
|| nr
>1) 627 origin
+= video_size_row
; 628 pos
+= video_size_row
; 629 scr_end
+= video_size_row
; 630 if(scr_end
> video_mem_end
) { 631 unsigned short* d
= (unsigned short*) video_mem_start
; 632 unsigned short* s
= (unsigned short*) origin
; 635 count
= (video_num_lines
-1)*video_num_columns
; 638 scr_writew(scr_readw(s
++),d
++); 640 count
= video_num_columns
; 643 scr_writew(video_erase_char
, d
++); 645 scr_end
-= origin
-video_mem_start
; 646 pos
-= origin
-video_mem_start
; 647 origin
= video_mem_start
; 649 if(currcons
== fg_console
) 655 d
= (unsigned short*) (scr_end
- video_size_row
); 656 count
= video_num_columns
; 659 scr_writew(video_erase_char
, d
++); 662 set_origin(currcons
); 664 unsigned short* d
= (unsigned short*) (origin
+video_size_row
*t
); 665 unsigned short* s
= (unsigned short*) (origin
+video_size_row
*(t
+nr
)); 667 memcpyw(d
, s
, (b
-t
-nr
) * video_size_row
); 668 memsetw(d
+ (b
-t
-nr
) * video_num_columns
, video_erase_char
, video_size_row
*nr
); 673 scrdown(int currcons
,unsigned int t
,unsigned int b
,unsigned int nr
) 681 if(b
> video_num_lines
|| t
>= b
|| nr
<1) 683 s
= (unsigned short*) (origin
+video_size_row
*(b
-nr
-1)); 684 step
= video_num_columns
* nr
; 687 memcpyw(s
+ step
, s
, video_size_row
); 688 s
-= video_num_columns
; 691 s
+= video_num_columns
; 692 memsetw(s
, video_erase_char
, video_size_row
); 698 * Routine to reset the visible "screen" to the top of video memory. 699 * This is necessary when exiting from the kernel back to a console 700 * which expects only the top of video memory to be used for the visible 701 * screen (with scrolling down by moving the memory contents). 702 * The normal action of the LINUX console is to scroll using all of the 703 * video memory and diddling the hardware top-of-video register as needed. 708 int currcons
= fg_console
; 709 unsigned short* d
= (unsigned short*) video_mem_start
; 710 unsigned short* s
= (unsigned short*) origin
; 713 count
= (video_num_lines
-1)*video_num_columns
; 714 memcpyw(d
, s
,2*count
); 715 memsetw(d
+ count
, video_erase_char
, 716 2*video_num_columns
); 717 scr_end
-= origin
-video_mem_start
; 718 pos
-= origin
-video_mem_start
; 719 origin
= video_mem_start
; 724 set_origin(currcons
); 725 set_cursor(currcons
); 728 static voidlf(int currcons
) 730 /* don't scroll if above bottom of scrolling region, or 731 * if below scrolling region 734 scrup(currcons
,top
,bottom
,1); 735 else if(y
< video_num_lines
-1) { 737 pos
+= video_size_row
; 742 static voidri(int currcons
) 744 /* don't scroll if below top of scrolling region, or 745 * if above scrolling region 748 scrdown(currcons
,top
,bottom
,1); 751 pos
-= video_size_row
; 756 staticinlinevoidcr(int currcons
) 762 staticinlinevoidbs(int currcons
) 771 staticinlinevoiddel(int currcons
) 776 static voidcsi_J(int currcons
,int vpar
) 779 unsigned short* start
; 782 case0:/* erase from cursor to end of display */ 783 count
= (scr_end
-pos
)>>1; 784 start
= (unsigned short*) pos
; 786 case1:/* erase from start to cursor */ 787 count
= ((pos
-origin
)>>1)+1; 788 start
= (unsigned short*) origin
; 790 case2:/* erase whole display */ 791 count
= video_num_columns
* video_num_lines
; 792 start
= (unsigned short*) origin
; 797 memsetw(start
, video_erase_char
,2*count
); 801 static voidcsi_K(int currcons
,int vpar
) 804 unsigned short* start
; 807 case0:/* erase from cursor to end of line */ 808 count
= video_num_columns
-x
; 809 start
= (unsigned short*) pos
; 811 case1:/* erase from start of line to cursor */ 812 start
= (unsigned short*) (pos
- (x
<<1)); 815 case2:/* erase whole line */ 816 start
= (unsigned short*) (pos
- (x
<<1)); 817 count
= video_num_columns
; 822 memsetw(start
, video_erase_char
,2* count
); 826 static voidcsi_X(int currcons
,int vpar
)/* erase the following vpar positions */ 831 memsetw((unsigned short*) pos
, video_erase_char
, 832 (vpar
> video_num_columns
-x
) ?2* (video_num_columns
-x
) :2* vpar
); 836 static voidupdate_attr(int currcons
) 841 attr
= (attr
&0xf0) | ulcolor
; 842 else if(intensity
==0) 843 attr
= (attr
&0xf0) | halfcolor
; 845 if(reverse
^ decscnm
) 846 attr
=reverse_video_char(attr
); 853 attr
= (attr
&0xf8) |0x01; 854 else if(intensity
==0) 855 attr
= (attr
&0xf0) |0x08; 858 video_erase_char
= (reverse_video_char(color
) <<8) |' '; 860 video_erase_char
= (color
<<8) |' '; 863 static voiddefault_attr(int currcons
) 872 static voidcsi_m(int currcons
) 878 case0:/* all attributes off */ 879 default_attr(currcons
); 896 case10:/* ANSI X3.64-1979 (SCO-ish?) 897 * Select primary font, don't display 898 * control chars if defined, don't set 901 translate
=set_translate(charset
==0 907 case11:/* ANSI X3.64-1979 (SCO-ish?) 908 * Select first alternate font, lets 909 * chars < 32 be displayed as ROM chars. 911 translate
=set_translate(IBMPC_MAP
); 915 case12:/* ANSI X3.64-1979 (SCO-ish?) 916 * Select second alternate font, toggle 917 * high bit before displaying as ROM char. 919 translate
=set_translate(IBMPC_MAP
); 936 case38:/* ANSI X3.64-1979 (SCO-ish?) 937 * Enables underscore, white foreground 938 * with white underscore (Linux - use 939 * default foreground). 941 color
= (def_color
&0x0f) | background
; 944 case39:/* ANSI X3.64-1979 (SCO-ish?) 945 * Disable underline option. 946 * Reset colour to default? It did this 949 color
= (def_color
&0x0f) | background
; 953 color
= (def_color
&0xf0) | foreground
; 956 if(par
[i
] >=30&& par
[i
] <=37) 957 color
= color_table
[par
[i
]-30] 959 else if(par
[i
] >=40&& par
[i
] <=47) 960 color
= (color_table
[par
[i
]-40]<<4) 964 update_attr(currcons
); 967 static voidrespond_string(const char* p
,struct tty_struct
* tty
) 970 tty_insert_flip_char(tty
, *p
,0); 973 tty_schedule_flip(tty
); 976 static voidcursor_report(int currcons
,struct tty_struct
* tty
) 980 sprintf(buf
,"\033[%ld;%ldR", y
+ (decom
? top
+1:1), x
+1); 981 respond_string(buf
, tty
); 984 staticinlinevoidstatus_report(struct tty_struct
* tty
) 986 respond_string("\033[0n", tty
);/* Terminal ok */ 989 staticinlinevoidrespond_ID(struct tty_struct
* tty
) 991 respond_string(VT102ID
, tty
); 994 voidmouse_report(struct tty_struct
* tty
,int butt
,int mrx
,int mry
) 998 sprintf(buf
,"\033[M%c%c%c", (char)(' '+ butt
), (char)('!'+ mrx
), 1000 respond_string(buf
, tty
); 1003 /* invoked via ioctl(TIOCLINUX) and through set_selection */ 1004 intmouse_reporting(void) 1006 int currcons
= fg_console
; 1008 return report_mouse
; 1011 inttioclinux(struct tty_struct
*tty
,unsigned long arg
) 1015 if(tty
->driver
.type
!= TTY_DRIVER_TYPE_CONSOLE
) 1017 if(current
->tty
!= tty
&& !suser()) 1019 if(get_user(type
, (char*)arg
)) 1024 returnset_selection(arg
, tty
,1); 1026 returnpaste_selection(tty
); 1028 do_unblank_screen(); 1031 returnsel_loadlut(arg
); 1035 * Make it possible to react to Shift+Mousebutton. 1036 * Note that 'shift_state' is an undocumented 1037 * kernel-internal variable; programs not closely 1038 * related to the kernel should not use this. 1041 return__put_user(data
, (char*) arg
); 1043 data
=mouse_reporting(); 1044 return__put_user(data
, (char*) arg
); 1046 set_vesa_blanking(arg
); 1048 case11:/* set kmsg redirect */ 1051 if(get_user(data
, (char*)arg
+1)) 1053 kmsg_redirect
= data
; 1055 case12:/* get fg_console */ 1061 staticinlineunsigned short*screenpos(int currcons
,int offset
,int viewed
) 1063 unsigned short*p
= (unsigned short*)(origin
+ offset
); 1064 if(viewed
&& currcons
== fg_console
) 1065 p
-= (__real_origin
- __origin
); 1069 /* Note: inverting the screen twice should revert to the original state */ 1070 voidinvert_screen(int currcons
,int offset
,int count
,int viewed
) 1075 p
=screenpos(currcons
, offset
, viewed
); 1078 unsigned short old
=scr_readw(p
); 1079 scr_writew(reverse_video_short(old
), p
); 1084 unsigned short old
=scr_readw(p
); 1085 scr_writew(old
^ (((old
&0x0700) ==0x0100) 1086 ?0x7000:0x7700), p
); 1091 /* used by selection: complement pointer position */ 1092 voidcomplement_pos(int currcons
,int offset
) 1094 static unsigned short*p
= NULL
; 1095 static unsigned short old
=0; 1102 p
=screenpos(currcons
, offset
,1); 1104 scr_writew(old
^0x7700, p
); 1108 /* used by selection */ 1109 unsigned shortscreen_word(int currcons
,int offset
,int viewed
) 1111 returnscr_readw(screenpos(currcons
, offset
, viewed
)); 1114 /* used by selection - convert a screen word to a glyph number */ 1115 intscrw2glyph(unsigned short scr_word
) 1117 return( video_mode_512ch
) 1118 ? ((scr_word
&0x0800) >>3) + (scr_word
&0x00ff) 1122 /* used by vcs - note the word offset */ 1123 unsigned short*screen_pos(int currcons
,int w_offset
,int viewed
) 1125 returnscreenpos(currcons
,2* w_offset
, viewed
); 1128 voidgetconsxy(int currcons
,char*p
) 1134 voidputconsxy(int currcons
,char*p
) 1136 gotoxy(currcons
, p
[0], p
[1]); 1137 set_cursor(currcons
); 1140 static voidset_mode(int currcons
,int on_off
) 1144 for(i
=0; i
<=npar
; i
++) 1145 if(ques
)switch(par
[i
]) {/* DEC private modes set/reset */ 1146 case1:/* Cursor keys send ^[Ox/^[[x */ 1152 case3:/* 80/132 mode switch unimplemented */ 1155 (void)vc_resize(video_num_lines
, deccolm
?132:80); 1156 /* this alone does not suffice; some user mode 1157 utility has to change the hardware regs */ 1160 case5:/* Inverted screen on/off */ 1161 if(decscnm
!= on_off
) { 1163 invert_screen(currcons
,0, video_screen_size
,0); 1164 update_attr(currcons
); 1167 case6:/* Origin relative/absolute */ 1169 gotoxay(currcons
,0,0); 1171 case7:/* Autowrap on/off */ 1174 case8:/* Autorepeat on/off */ 1181 report_mouse
= on_off
?1:0; 1183 case25:/* Cursor on/off */ 1185 set_cursor(currcons
); 1188 report_mouse
= on_off
?2:0; 1190 }else switch(par
[i
]) {/* ANSI modes set/reset */ 1191 case3:/* Monitor (display ctrls) */ 1194 case4:/* Insert Mode on/off */ 1197 case20:/* Lf, Enter == CrLf/Lf */ 1206 static voidsetterm_command(int currcons
) 1209 case1:/* set color for underline mode */ 1210 if(can_do_color
&& par
[1] <16) { 1211 ulcolor
= color_table
[par
[1]]; 1213 update_attr(currcons
); 1216 case2:/* set color for half intensity mode */ 1217 if(can_do_color
&& par
[1] <16) { 1218 halfcolor
= color_table
[par
[1]]; 1220 update_attr(currcons
); 1223 case8:/* store colors as defaults */ 1225 default_attr(currcons
); 1226 update_attr(currcons
); 1228 case9:/* set blanking interval */ 1229 blankinterval
= ((par
[1] <60) ? par
[1] :60) *60* HZ
; 1230 poke_blanked_console(); 1232 case10:/* set bell frequency in Hz */ 1234 bell_pitch
= par
[1]; 1236 bell_pitch
= DEFAULT_BELL_PITCH
; 1238 case11:/* set bell duration in msec */ 1240 bell_duration
= (par
[1] <2000) ? 1243 bell_duration
= DEFAULT_BELL_DURATION
; 1245 case12:/* bring specified console to the front */ 1246 if(par
[1] >=1&&vc_cons_allocated(par
[1]-1)) 1247 update_screen(par
[1]-1); 1249 case13:/* unblank the screen */ 1252 case14:/* set vesa powerdown interval */ 1253 vesa_off_interval
= ((par
[1] <60) ? par
[1] :60) *60* HZ
; 1258 static voidinsert_char(int currcons
) 1261 unsigned short tmp
, old
= video_erase_char
; 1262 unsigned short* p
= (unsigned short*) pos
; 1264 while(i
++ < video_num_columns
) { 1273 static voidinsert_line(int currcons
,unsigned int nr
) 1275 scrdown(currcons
,y
,bottom
,nr
); 1279 static voiddelete_char(int currcons
) 1282 unsigned short* p
= (unsigned short*) pos
; 1284 while(++i
< video_num_columns
) { 1285 scr_writew(scr_readw(p
+1), p
); 1288 scr_writew(video_erase_char
, p
); 1292 static voiddelete_line(int currcons
,unsigned int nr
) 1294 scrup(currcons
,y
,bottom
,nr
); 1298 static voidcsi_at(int currcons
,unsigned int nr
) 1300 if(nr
> video_num_columns
) 1301 nr
= video_num_columns
; 1305 insert_char(currcons
); 1308 static voidcsi_L(int currcons
,unsigned int nr
) 1310 if(nr
> video_num_lines
) 1311 nr
= video_num_lines
; 1314 insert_line(currcons
, nr
); 1317 static voidcsi_P(int currcons
,unsigned int nr
) 1319 if(nr
> video_num_columns
) 1320 nr
= video_num_columns
; 1324 delete_char(currcons
); 1327 static voidcsi_M(int currcons
,unsigned int nr
) 1329 if(nr
> video_num_lines
) 1330 nr
= video_num_lines
; 1333 delete_line(currcons
, nr
); 1336 static voidsave_cur(int currcons
) 1340 s_intensity
= intensity
; 1341 s_underline
= underline
; 1343 s_reverse
= reverse
; 1344 s_charset
= charset
; 1346 saved_G0
= G0_charset
; 1347 saved_G1
= G1_charset
; 1350 static voidrestore_cur(int currcons
) 1352 gotoxy(currcons
,saved_x
,saved_y
); 1353 intensity
= s_intensity
; 1354 underline
= s_underline
; 1356 reverse
= s_reverse
; 1357 charset
= s_charset
; 1359 G0_charset
= saved_G0
; 1360 G1_charset
= saved_G1
; 1361 translate
=set_translate(charset
? G1_charset
: G0_charset
); 1362 update_attr(currcons
); 1366 enum{ ESnormal
, ESesc
, ESsquare
, ESgetpars
, ESgotpars
, ESfunckey
, 1367 EShash
, ESsetG0
, ESsetG1
, ESpercent
, ESignore
, ESnonstd
, 1370 static voidreset_terminal(int currcons
,int do_clear
) 1373 bottom
= video_num_lines
; 1374 vc_state
= ESnormal
; 1376 translate
=set_translate(LAT1_MAP
); 1377 G0_charset
= LAT1_MAP
; 1378 G1_charset
= GRAF_MAP
; 1398 kbd_table
[currcons
].lockstate
=0; 1399 kbd_table
[currcons
].slockstate
=0; 1400 kbd_table
[currcons
].ledmode
= LED_SHOW_FLAGS
; 1401 kbd_table
[currcons
].ledflagstate
= kbd_table
[currcons
].default_ledflagstate
; 1404 default_attr(currcons
); 1405 update_attr(currcons
); 1407 tab_stop
[0] =0x01010100; 1411 tab_stop
[4] =0x01010101; 1413 bell_pitch
= DEFAULT_BELL_PITCH
; 1414 bell_duration
= DEFAULT_BELL_DURATION
; 1416 gotoxy(currcons
,0,0); 1423 * Turn the Scroll-Lock LED on when the tty is stopped 1425 static voidcon_stop(struct tty_struct
*tty
) 1430 console_num
=MINOR(tty
->device
) - (tty
->driver
.minor_start
); 1431 if(!vc_cons_allocated(console_num
)) 1434 set_vc_kbd_led(kbd_table
+ console_num
, VC_SCROLLOCK
); 1440 * Turn the Scroll-Lock LED off when the console is started 1442 static voidcon_start(struct tty_struct
*tty
) 1447 console_num
=MINOR(tty
->device
) - (tty
->driver
.minor_start
); 1448 if(!vc_cons_allocated(console_num
)) 1451 clr_vc_kbd_led(kbd_table
+ console_num
, VC_SCROLLOCK
); 1456 static voidcon_flush_chars(struct tty_struct
*tty
) 1458 unsigned int currcons
; 1459 struct vt_struct
*vt
= (struct vt_struct
*)tty
->driver_data
; 1461 currcons
= vt
->vc_num
; 1462 if(vcmode
!= KD_GRAPHICS
) 1463 set_cursor(currcons
); 1466 static intdo_con_write(struct tty_struct
* tty
,int from_user
, 1467 const unsigned char*buf
,int count
) 1469 int c
, tc
, ok
, n
=0; 1470 unsigned int currcons
; 1471 struct vt_struct
*vt
= (struct vt_struct
*)tty
->driver_data
; 1474 ap_write(1,buf
,count
); 1478 currcons
= vt
->vc_num
; 1479 if(!vc_cons_allocated(currcons
)) { 1480 /* could this happen? */ 1481 static int error
=0; 1484 printk("con_write: tty %d not allocated\n", currcons
+1); 1489 if(currcons
== sel_cons
) 1493 /* just to make sure that noone lurks at places he shouldn't see. */ 1494 if(verify_area(VERIFY_READ
, buf
, count
)) 1495 return0;/* ?? are error codes legal here ?? */ 1498 disable_bh(CONSOLE_BH
); 1499 while(!tty
->stopped
&& count
) { 1500 enable_bh(CONSOLE_BH
); 1505 buf
++; n
++; count
--; 1506 disable_bh(CONSOLE_BH
); 1509 /* Combine UTF-8 into Unicode */ 1510 /* Incomplete characters silently ignored */ 1512 if(utf_count
>0&& (c
&0xc0) ==0x80) { 1513 utf_char
= (utf_char
<<6) | (c
&0x3f); 1519 if((c
&0xe0) ==0xc0) { 1521 utf_char
= (c
&0x1f); 1522 }else if((c
&0xf0) ==0xe0) { 1524 utf_char
= (c
&0x0f); 1525 }else if((c
&0xf8) ==0xf0) { 1527 utf_char
= (c
&0x07); 1528 }else if((c
&0xfc) ==0xf8) { 1530 utf_char
= (c
&0x03); 1531 }else if((c
&0xfe) ==0xfc) { 1533 utf_char
= (c
&0x01); 1543 tc
= translate
[toggle_meta
? (c
|0x80) : c
]; 1546 /* If the original code was a control character we 1547 * only allow a glyph to be displayed if the code is 1548 * not normally used (such as for cursor movement) or 1549 * if the disp_ctrl mode has been explicitly enabled. 1550 * Certain characters (as given by the CTRL_ALWAYS 1551 * bitmap) are always displayed as control characters, 1552 * as the console would be pretty useless without 1553 * them; to display an arbitrary font position use the 1554 * direct-to-font zone in UTF-8 mode. 1556 ok
= tc
&& (c
>=32|| 1557 (!utf
&& !(((disp_ctrl
? CTRL_ALWAYS
1558 : CTRL_ACTION
) >> c
) &1))) 1559 && (c
!=127|| disp_ctrl
) 1562 if(vc_state
== ESnormal
&& ok
) { 1563 /* Now try to find out how to display it */ 1564 tc
=conv_uni_to_pc(tc
); 1566 /* If we got -4 (not found) then see if we have 1567 defined a replacement character (U+FFFD) */ 1568 tc
=conv_uni_to_pc(0xfffd); 1570 /* One reason for the -4 can be that we just 1571 did a clear_unimap(); 1572 try at least to show something. */ 1575 }else if( tc
== -3) { 1576 /* Bad hash table -- hope for the best */ 1579 if(tc
& ~console_charmask
) 1580 continue;/* Conversion failed */ 1587 insert_char(currcons
); 1588 scr_writew( video_mode_512ch
? 1589 ((attr
&0xf7) <<8) + ((tc
&0x100) <<3) + 1590 (tc
&0x0ff) : (attr
<<8) + tc
, 1591 (unsigned short*) pos
); 1592 if(x
== video_num_columns
-1) 1602 * Control characters can be used in the _middle_ 1603 * of an escape sequence. 1610 kd_mksound(bell_pitch
, bell_duration
); 1617 while(x
< video_num_columns
-1) { 1619 if(tab_stop
[x
>>5] & (1<< (x
&31))) 1624 case10:case11:case12: 1633 translate
=set_translate(G1_charset
); 1638 translate
=set_translate(G0_charset
); 1642 vc_state
= ESnormal
; 1651 vc_state
= ESsquare
; 1656 vc_state
= ESnormal
; 1659 vc_state
= ESsquare
; 1662 vc_state
= ESnonstd
; 1665 vc_state
= ESpercent
; 1678 tab_stop
[x
>>5] |= (1<< (x
&31)); 1687 restore_cur(currcons
); 1699 reset_terminal(currcons
,1); 1701 case'>':/* Numeric keypad */ 1704 case'=':/* Appl. keypad */ 1710 if(c
=='P') {/* palette escape sequence */ 1711 for(npar
=0; npar
<NPAR
; npar
++) 1714 vc_state
= ESpalette
; 1716 }else if(c
=='R') {/* reset palette */ 1717 reset_palette(currcons
); 1718 vc_state
= ESnormal
; 1720 vc_state
= ESnormal
; 1723 if( (c
>='0'&&c
<='9') || (c
>='A'&&c
<='F') || (c
>='a'&&c
<='f') ) { 1724 par
[npar
++] = (c
>'9'? (c
&0xDF)-'A'+10: c
-'0') ; 1726 int i
= par
[0]*3, j
=1; 1727 palette
[i
] =16*par
[j
++]; 1728 palette
[i
++] += par
[j
++]; 1729 palette
[i
] =16*par
[j
++]; 1730 palette
[i
++] += par
[j
++]; 1731 palette
[i
] =16*par
[j
++]; 1732 palette
[i
] += par
[j
]; 1734 vc_state
= ESnormal
; 1737 vc_state
= ESnormal
; 1740 for(npar
=0; npar
< NPAR
; npar
++) 1743 vc_state
= ESgetpars
; 1744 if(c
=='[') {/* Function key */ 1752 if(c
==';'&& npar
<NPAR
-1) { 1755 }else if(c
>='0'&& c
<='9') { 1759 }else vc_state
=ESgotpars
; 1761 vc_state
= ESnormal
; 1764 set_mode(currcons
,1); 1767 set_mode(currcons
,0); 1774 cursor_report(currcons
,tty
); 1783 if(par
[0]) par
[0]--; 1784 gotoxy(currcons
,par
[0],y
); 1787 if(!par
[0]) par
[0]++; 1788 gotoxy(currcons
,x
,y
-par
[0]); 1791 if(!par
[0]) par
[0]++; 1792 gotoxy(currcons
,x
,y
+par
[0]); 1795 if(!par
[0]) par
[0]++; 1796 gotoxy(currcons
,x
+par
[0],y
); 1799 if(!par
[0]) par
[0]++; 1800 gotoxy(currcons
,x
-par
[0],y
); 1803 if(!par
[0]) par
[0]++; 1804 gotoxy(currcons
,0,y
+par
[0]); 1807 if(!par
[0]) par
[0]++; 1808 gotoxy(currcons
,0,y
-par
[0]); 1811 if(par
[0]) par
[0]--; 1812 gotoxay(currcons
,x
,par
[0]); 1815 if(par
[0]) par
[0]--; 1816 if(par
[1]) par
[1]--; 1817 gotoxay(currcons
,par
[1],par
[0]); 1820 csi_J(currcons
,par
[0]); 1823 csi_K(currcons
,par
[0]); 1826 csi_L(currcons
,par
[0]); 1829 csi_M(currcons
,par
[0]); 1832 csi_P(currcons
,par
[0]); 1840 tab_stop
[x
>>5] &= ~(1<< (x
&31)); 1841 else if(par
[0] ==3) { 1852 case'q':/* DECLL - but only 3 leds */ 1853 /* map 0,1,2,3 to 0,1,2,4 */ 1855 setledstate(kbd_table
+ currcons
, 1856 (par
[0] <3) ? par
[0] :4); 1862 par
[1] = video_num_lines
; 1863 /* Minimum allowed region is 2 lines */ 1864 if(par
[0] < par
[1] && 1865 par
[1] <= video_num_lines
) { 1868 gotoxay(currcons
,0,0); 1875 restore_cur(currcons
); 1878 csi_X(currcons
, par
[0]); 1881 csi_at(currcons
,par
[0]); 1883 case']':/* setterm functions */ 1884 setterm_command(currcons
); 1889 vc_state
= ESnormal
; 1891 case'@':/* defined in ISO 2022 */ 1894 case'G':/* prelim official escape code */ 1895 case'8':/* retained for compatibility */ 1901 vc_state
= ESnormal
; 1904 vc_state
= ESnormal
; 1906 /* DEC screen alignment test. kludge :-) */ 1908 (video_erase_char
&0xff00) |'E'; 1911 (video_erase_char
&0xff00) |' '; 1916 G0_charset
= GRAF_MAP
; 1918 G0_charset
= LAT1_MAP
; 1920 G0_charset
= IBMPC_MAP
; 1922 G0_charset
= USER_MAP
; 1924 translate
=set_translate(G0_charset
); 1925 vc_state
= ESnormal
; 1929 G1_charset
= GRAF_MAP
; 1931 G1_charset
= LAT1_MAP
; 1933 G1_charset
= IBMPC_MAP
; 1935 G1_charset
= USER_MAP
; 1937 translate
=set_translate(G1_charset
); 1938 vc_state
= ESnormal
; 1941 vc_state
= ESnormal
; 1944 enable_bh(CONSOLE_BH
); 1948 static intcon_write(struct tty_struct
* tty
,int from_user
, 1949 const unsigned char*buf
,int count
) 1953 retval
=do_con_write(tty
, from_user
, buf
, count
); 1954 con_flush_chars(tty
); 1959 static voidcon_put_char(struct tty_struct
*tty
,unsigned char ch
) 1961 do_con_write(tty
,0, &ch
,1); 1964 static intcon_write_room(struct tty_struct
*tty
) 1968 return4096;/* No limit, really; we're not buffering */ 1971 static intcon_chars_in_buffer(struct tty_struct
*tty
) 1973 return0;/* we're not buffering */ 1976 voidpoke_blanked_console(void) 1978 timer_active
&= ~(1<<BLANK_TIMER
); 1979 if(vt_cons
[fg_console
]->vc_mode
== KD_GRAPHICS
) 1981 if(console_blanked
) { 1982 timer_table
[BLANK_TIMER
].fn
= unblank_screen
; 1983 timer_table
[BLANK_TIMER
].expires
=0; 1984 timer_active
|=1<<BLANK_TIMER
; 1985 }else if(blankinterval
) { 1986 timer_table
[BLANK_TIMER
].expires
= jiffies
+ blankinterval
; 1987 timer_active
|=1<<BLANK_TIMER
; 1991 #ifdef CONFIG_VT_CONSOLE 1992 voidvt_console_print(struct console
*co
,const char* b
,unsigned count
) 1994 int currcons
= fg_console
; 1996 static int printing
=0; 2002 if(!printable
|| printing
) 2003 return;/* console not yet initialized */ 2006 if(kmsg_redirect
&&vc_cons_allocated(kmsg_redirect
-1)) 2007 currcons
= kmsg_redirect
-1; 2009 if(!vc_cons_allocated(currcons
)) { 2011 printk("vt_console_print: tty %d not allocated ??\n", currcons
+1); 2015 #ifdef CONFIG_SERIAL_ECHO 2016 serial_echo_print(b
); 2017 #endif/* CONFIG_SERIAL_ECHO */ 2021 if(c
==10|| c
==13|| need_wrap
) { 2028 if(c
==8) {/* backspace */ 2032 scr_writew((attr
<<8) + c
, (unsigned short*) pos
); 2033 if(x
== video_num_columns
-1) { 2040 set_cursor(currcons
); 2041 poke_blanked_console(); 2045 static kdev_t
vt_console_device(struct console
*c
) 2047 returnMKDEV(TTY_MAJOR
, c
->index
? c
->index
: fg_console
+1); 2050 externintkeyboard_wait_for_keypress(struct console
*); 2052 struct console vt_console_driver
= { 2057 keyboard_wait_for_keypress
, 2068 * con_throttle and con_unthrottle are only used for 2069 * paste_selection(), which has to stuff in a large number of 2072 static voidcon_throttle(struct tty_struct
*tty
) 2076 static voidcon_unthrottle(struct tty_struct
*tty
) 2078 struct vt_struct
*vt
= (struct vt_struct
*) tty
->driver_data
; 2080 wake_up_interruptible(&vt
->paste_wait
); 2083 static voidvc_init(unsigned int currcons
,unsigned long rows
,unsigned long cols
,int do_clear
) 2085 long base
= (long) vc_scrbuf
[currcons
]; 2088 video_num_columns
= cols
; 2089 video_num_lines
= rows
; 2090 video_size_row
= cols
<<1; 2091 video_screen_size
= video_num_lines
* video_size_row
; 2093 pos
= origin
= video_mem_start
= base
; 2094 scr_end
= base
+ video_screen_size
; 2095 video_mem_end
= base
+ video_screen_size
; 2097 for(j
=k
=0; j
<16; j
++) { 2098 vc_cons
[currcons
].d
->vc_palette
[k
++] = default_red
[j
] ; 2099 vc_cons
[currcons
].d
->vc_palette
[k
++] = default_grn
[j
] ; 2100 vc_cons
[currcons
].d
->vc_palette
[k
++] = default_blu
[j
] ; 2102 def_color
=0x07;/* white */ 2103 ulcolor
=0x0f;/* bold white */ 2104 halfcolor
=0x08;/* grey */ 2105 vt_cons
[currcons
]->paste_wait
=0; 2106 reset_terminal(currcons
, do_clear
); 2109 static voidcon_setsize(unsigned long rows
,unsigned long cols
) 2111 video_num_lines
= rows
; 2112 video_num_columns
= cols
; 2113 video_size_row
=2* cols
; 2114 video_screen_size
= video_num_lines
* video_size_row
; 2118 * This is the console switching bottom half handler. 2120 * Doing console switching in a bottom half handler allows 2121 * us to do the switches asynchronously (needed when we want 2122 * to switch due to a keyboard interrupt), while still giving 2123 * us the option to easily disable it to avoid races when we 2124 * need to write to the console. 2126 static voidconsole_bh(void) 2128 if(want_console
>=0) { 2129 if(want_console
!= fg_console
) { 2130 change_console(want_console
); 2131 /* we only changed when the console had already 2132 been allocated - a new console is not created 2133 in an interrupt routine */ 2137 if(do_poke_blanked_console
) {/* do not unblank for a LED change */ 2138 do_poke_blanked_console
=0; 2139 poke_blanked_console(); 2144 * unsigned long con_init(unsigned long); 2146 * This routine initializes console interrupts, and does nothing 2147 * else. If you want the screen to clear, call tty_write with 2148 * the appropriate escape-sequence. 2150 * Reads the information preserved by setup.s to determine the current display 2151 * type and sets everything accordingly. 2153 * FIXME: return early if we don't _have_ a video card installed. 2156 __initfunc(unsigned longcon_init(unsigned long kmem_start
)) 2158 const char*display_desc
="????"; 2160 int orig_x
= ORIG_X
; 2161 int orig_y
= ORIG_Y
; 2164 if(serial_console
) { 2167 #if CONFIG_SUN_SERIAL 2168 rs_cons_hook(0,0, serial_console
); 2169 rs_cons_hook(0,1, serial_console
); 2176 memset(&console_driver
,0,sizeof(struct tty_driver
)); 2177 console_driver
.magic
= TTY_DRIVER_MAGIC
; 2178 console_driver
.name
="tty"; 2179 console_driver
.name_base
=1; 2180 console_driver
.major
= TTY_MAJOR
; 2181 console_driver
.minor_start
=1; 2182 console_driver
.num
= MAX_NR_CONSOLES
; 2183 console_driver
.type
= TTY_DRIVER_TYPE_CONSOLE
; 2184 console_driver
.init_termios
= tty_std_termios
; 2185 console_driver
.flags
= TTY_DRIVER_REAL_RAW
| TTY_DRIVER_RESET_TERMIOS
; 2186 console_driver
.refcount
= &console_refcount
; 2187 console_driver
.table
= console_table
; 2188 console_driver
.termios
= console_termios
; 2189 console_driver
.termios_locked
= console_termios_locked
; 2191 console_driver
.open
= con_open
; 2192 console_driver
.write
= con_write
; 2193 console_driver
.write_room
= con_write_room
; 2194 console_driver
.put_char
= con_put_char
; 2195 console_driver
.flush_chars
= con_flush_chars
; 2196 console_driver
.chars_in_buffer
= con_chars_in_buffer
; 2197 console_driver
.ioctl
= vt_ioctl
; 2198 console_driver
.stop
= con_stop
; 2199 console_driver
.start
= con_start
; 2200 console_driver
.throttle
= con_throttle
; 2201 console_driver
.unthrottle
= con_unthrottle
; 2203 if(tty_register_driver(&console_driver
)) 2204 panic("Couldn't register console driver\n"); 2209 con_setsize(ORIG_VIDEO_LINES
, ORIG_VIDEO_COLS
); 2211 timer_table
[BLANK_TIMER
].fn
= blank_screen
; 2212 timer_table
[BLANK_TIMER
].expires
=0; 2214 timer_table
[BLANK_TIMER
].expires
= jiffies
+ blankinterval
; 2215 timer_active
|=1<<BLANK_TIMER
; 2218 kmem_start
=con_type_init(kmem_start
, &display_desc
); 2220 hardscroll_enabled
= (hardscroll_disabled_by_init
?0: 2221 (video_type
== VIDEO_TYPE_EGAC
2222 || video_type
== VIDEO_TYPE_VGAC
2223 || video_type
== VIDEO_TYPE_EGAM
)); 2226 /* Due to kmalloc roundup allocating statically is more efficient - 2227 so provide MIN_NR_CONSOLES for people with very little memory */ 2228 for(currcons
=0; currcons
< MIN_NR_CONSOLES
; currcons
++) { 2231 vc_cons
[currcons
].d
= (struct vc_data
*) kmem_start
; 2232 kmem_start
+=sizeof(struct vc_data
); 2233 vt_cons
[currcons
] = (struct vt_struct
*) kmem_start
; 2234 kmem_start
+=sizeof(struct vt_struct
); 2235 vc_scrbuf
[currcons
] = (unsigned short*) kmem_start
; 2236 kmem_start
+= video_screen_size
; 2238 screenbuf_size
= video_screen_size
; 2239 vc_init(currcons
, video_num_lines
, video_num_columns
, currcons
); 2240 for(j
=k
=0; j
<16; j
++) { 2241 vc_cons
[currcons
].d
->vc_palette
[k
++] = default_red
[j
] ; 2242 vc_cons
[currcons
].d
->vc_palette
[k
++] = default_grn
[j
] ; 2243 vc_cons
[currcons
].d
->vc_palette
[k
++] = default_blu
[j
] ; 2247 currcons
= fg_console
=0; 2249 video_mem_start
= video_mem_base
; 2250 video_mem_end
= video_mem_term
; 2251 origin
= video_mem_start
; 2252 scr_end
= video_mem_start
+ video_num_lines
* video_size_row
; 2253 gotoxy(currcons
,orig_x
,orig_y
); 2254 set_origin(currcons
); 2257 /* Figure out the size of the screen and screen font so we 2258 can figure out the appropriate screen size should we load 2262 if( video_type
== VIDEO_TYPE_VGAC
|| video_type
== VIDEO_TYPE_EGAC
2263 || video_type
== VIDEO_TYPE_EGAM
|| video_type
== VIDEO_TYPE_TGAC
2264 || video_type
== VIDEO_TYPE_SUN
) 2266 default_font_height
= video_font_height
= ORIG_VIDEO_POINTS
; 2267 /* This may be suboptimal but is a safe bet - go with it */ 2268 video_scan_lines
= video_font_height
* video_num_lines
; 2270 #ifdef CONFIG_SERIAL_ECHO 2271 serial_echo_init(SERIAL_ECHO_PORT
); 2272 #endif/* CONFIG_SERIAL_ECHO */ 2274 printk("Console: %ld point font, %ld scans\n", 2275 video_font_height
, video_scan_lines
); 2278 printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n", 2279 can_do_color
?"colour":"mono", 2280 display_desc
, video_num_columns
, video_num_lines
, 2281 MIN_NR_CONSOLES
, (MIN_NR_CONSOLES
==1) ?"":"s", 2284 con_type_init_finish(); 2287 * can't register TGA yet, because PCI bus probe has *not* taken 2288 * place before con_init() gets called. Trigger the real TGA hw 2289 * initialization and register_console() event from 2290 * within the bus probing code... :-( 2292 #ifdef CONFIG_VT_CONSOLE 2293 if(video_type
!= VIDEO_TYPE_TGAC
&&con_is_present()) 2294 register_console(&vt_console_driver
); 2297 init_bh(CONSOLE_BH
, console_bh
); 2301 voidvesa_powerdown_screen(void) 2303 timer_active
&= ~(1<<BLANK_TIMER
); 2304 timer_table
[BLANK_TIMER
].fn
= unblank_screen
; 2309 voiddo_blank_screen(int nopowersave
) 2316 if(vesa_off_interval
&& !nopowersave
) { 2317 timer_table
[BLANK_TIMER
].fn
= vesa_powerdown_screen
; 2318 timer_table
[BLANK_TIMER
].expires
= jiffies
+ vesa_off_interval
; 2319 timer_active
|= (1<<BLANK_TIMER
); 2321 timer_active
&= ~(1<<BLANK_TIMER
); 2322 timer_table
[BLANK_TIMER
].fn
= unblank_screen
; 2325 /* try not to lose information by blanking, and not to waste memory */ 2326 currcons
= fg_console
; 2328 blank__origin
= __origin
; 2329 blank_origin
= origin
; 2330 set_origin(fg_console
); 2331 get_scrmem(fg_console
); 2332 unblank_origin
= origin
; 2333 memsetw((void*)blank_origin
, BLANK
, 2334 2*video_num_lines
*video_num_columns
); 2336 console_blanked
= fg_console
+1; 2341 if(apm_display_blank()) 2348 voiddo_unblank_screen(void) 2354 if(!console_blanked
) 2356 if(!vc_cons_allocated(fg_console
)) { 2358 printk("unblank_screen: tty %d not allocated ??\n", fg_console
+1); 2361 timer_table
[BLANK_TIMER
].fn
= blank_screen
; 2363 timer_table
[BLANK_TIMER
].expires
= jiffies
+ blankinterval
; 2364 timer_active
|=1<<BLANK_TIMER
; 2367 currcons
= fg_console
; 2370 if(console_blanked
== fg_console
+1&& origin
== unblank_origin
2372 /* try to restore the exact situation before blanking */ 2374 offset
= (blank_origin
- video_mem_base
) 2375 - (unblank_origin
- video_mem_start
); 2379 set_scrmem(fg_console
, offset
); 2380 set_origin(fg_console
); 2381 set_cursor(fg_console
); 2383 __set_origin(blank__origin
); 2387 if(apm_display_unblank()) 2393 * If a blank_screen is due to a timer, then a power save is allowed. 2394 * If it is related to console_switching, then avoid vesa_blank(). 2396 static voidblank_screen(void) 2401 static voidunblank_screen(void) 2403 do_unblank_screen(); 2406 voidupdate_screen(int new_console
) 2410 if(new_console
== fg_console
|| lock
) 2412 if(!vc_cons_allocated(new_console
)) { 2414 printk("update_screen: tty %d not allocated ??\n", new_console
+1); 2421 if(!console_blanked
) 2422 get_scrmem(fg_console
); 2424 console_blanked
= -1;/* no longer of the form console+1 */ 2425 fg_console
= new_console
;/* this is the only (nonzero) assignment to fg_console */ 2426 /* consequently, fg_console will always be allocated */ 2427 set_scrmem(fg_console
,0); 2428 set_origin(fg_console
); 2429 set_cursor(fg_console
); 2431 compute_shiftstate(); 2436 * Allocate the console screen memory. 2438 static intcon_open(struct tty_struct
*tty
,struct file
* filp
) 2443 idx
=MINOR(tty
->device
) - tty
->driver
.minor_start
; 2445 i
=vc_allocate(idx
); 2449 vt_cons
[idx
]->vc_num
= idx
; 2450 tty
->driver_data
= vt_cons
[idx
]; 2452 if(!tty
->winsize
.ws_row
&& !tty
->winsize
.ws_col
) { 2453 tty
->winsize
.ws_row
= video_num_lines
; 2454 tty
->winsize
.ws_col
= video_num_columns
; 2461 * Load palette into the EGA/VGA DAC registers. arg points to a colour 2462 * map, 3 bytes per colour, 16 colours, range from 0 to 255. 2465 intcon_set_cmap(unsigned char*arg
) 2467 returnset_get_cmap(arg
,1); 2470 intcon_get_cmap(unsigned char*arg
) 2472 returnset_get_cmap(arg
,0); 2475 voidreset_palette(int currcons
) 2478 for(j
=k
=0; j
<16; j
++) { 2479 palette
[k
++] = default_red
[j
]; 2480 palette
[k
++] = default_grn
[j
]; 2481 palette
[k
++] = default_blu
[j
]; 2487 * Load font into the EGA/VGA character generator. arg points to a 8192 2488 * byte map, 32 bytes per character. Only first H of them are used for 2489 * 8xH fonts (0 < H <= 32). 2492 intcon_set_font(char*arg
,int ch512
) 2496 i
=set_get_font(arg
,1,ch512
); 2498 hashtable_contents_valid
=0; 2499 video_mode_512ch
= ch512
; 2500 console_charmask
= ch512
?0x1ff:0x0ff; 2505 intcon_get_font(char*arg
) 2507 returnset_get_font(arg
,0,video_mode_512ch
);