Import 2.1.92pre2
[davej-history.git] / drivers / char / console.c
blob73634b1db191b0dd62d452f22b42b3d6b74f857c
1 /*
2 * linux/drivers/char/console.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6 /*
7 * console.c
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
58 * <poe@daimi.aau.dk>
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>
66 #define BLANK 0x0020
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>
99 #include <linux/kd.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>
105 #ifdef CONFIG_APM
106 #include <linux/apm_bios.h>
107 #endif
109 #include <asm/io.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>
120 #ifndef MIN
121 #define MIN(a,b) ((a) < (b) ? (a) : (b))
122 #endif
124 #ifdef __sparc__
125 int serial_console;
126 #endif
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;
179 int can_do_color =0;
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,
202 int fg_console =0;
203 int last_console =0;
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 \
230 do { \
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)
241 int lsr, ier;
242 int i;
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++) {
256 WAIT_FOR_XMITR;
258 /* Send the character out. */
259 serial_echo_outb(*s, UART_TX);
261 /* if a LF, also do CR... */
262 if(*s ==10) {
263 WAIT_FOR_XMITR;
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);
277 return(0);
282 serial_echo_init(int base)
284 int comstat, hi, lo;
286 if(base !=0x2f8&& base !=0x3f8) {
287 serial_echo_port =0;
288 return(0);
289 }else
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
311 * registers
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 */
317 return(0);
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)
330 return-ENXIO;
331 if(!vc_cons[i].d) {
332 long p, q;
334 /* prevent users from taking too much memory */
335 if(i >= MAX_NR_USER_CONSOLES && !suser())
336 return-EPERM;
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);
342 if(!q)
343 return-ENOMEM;
344 p = (long)kmalloc(structsize, GFP_KERNEL);
345 if(!p) {
346 kfree_s((char*) q, video_screen_size);
347 return-ENOMEM;
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);
358 return0;
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;
370 unsigned short*p;
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);
377 sr = cc <<1;
378 ss = sr * ll;
380 if(ss > video_mem_term - video_mem_base)
381 return-ENOMEM;
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
387 * of the same size.
389 for(currcons =0; currcons < MAX_NR_CONSOLES; currcons++) {
390 if(!vc_cons_allocated(currcons))
391 newscreens[currcons] =0;
392 else{
393 p = (unsigned short*)kmalloc(ss, GFP_USER);
394 if(!p) {
395 for(i =0; i< currcons; i++)
396 if(newscreens[i])
397 kfree_s(newscreens[i], ss);
398 return-ENOMEM;
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;
413 video_size_row = sr;
414 video_screen_size = ss;
416 for(currcons =0; currcons < MAX_NR_CONSOLES; currcons++) {
417 if(!vc_cons_allocated(currcons))
418 continue;
420 rlth =MIN(osr, sr);
421 rrem = sr - rlth;
422 ol = origin;
423 nl = (long) newscreens[currcons];
424 if(ll < oll)
425 ol += (oll - ll) * osr;
427 while(ol < scr_end) {
428 memcpyw((unsigned short*) nl, (unsigned short*) ol, rlth);
429 if(rrem)
430 memsetw((void*)(nl + rlth), video_erase_char, rrem);
431 ol += osr;
432 nl += sr;
435 if(kmalloced)
436 kfree_s(vc_scrbuf[currcons], screenbuf_size);
437 vc_scrbuf[currcons] = newscreens[currcons];
438 kmalloced =1;
439 screenbuf_size = ss;
441 origin = video_mem_start = (long) vc_scrbuf[currcons];
442 scr_end = video_mem_end = video_mem_start + ss;
444 if(scr_end > nl)
445 memsetw((void*) nl, video_erase_char, scr_end - nl);
447 /* do part of a reset_terminal() */
448 top =0;
449 bottom = video_num_lines;
450 gotoxy(currcons, x, y);
451 save_cur(currcons);
454 set_scrmem(fg_console,0);
455 set_origin(fg_console);
456 set_cursor(fg_console);
458 return0;
461 voidvc_disallocate(unsigned int currcons)
463 if(vc_cons_allocated(currcons)) {
464 if(kmalloced)
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
480 #define lnm VC_CRLF
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)
506 int min_y, max_y;
508 if(new_x <0)
509 x =0;
510 else
511 if(new_x >= video_num_columns)
512 x = video_num_columns -1;
513 else
514 x = new_x;
515 if(decom) {
516 min_y = top;
517 max_y = bottom;
518 }else{
519 min_y =0;
520 max_y = video_num_lines;
522 if(new_y < min_y)
523 y = min_y;
524 else if(new_y >= max_y)
525 y = max_y -1;
526 else
527 y = new_y;
528 pos = origin + y*video_size_row + (x<<1);
529 need_wrap =0;
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)
561 int new_origin;
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;
568 if(new_origin <0) {
569 int s_top = __real_origin + video_num_lines*video_num_columns;
570 new_origin += last_origin_rel;
571 if(new_origin < s_top)
572 new_origin = s_top;
573 if(new_origin > last_origin_rel - video_num_columns
574 || has_wrapped ==0)
575 new_origin =0;
576 else{
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;
580 while(count) {
581 count--;
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)
593 if(!lines)
594 lines = video_num_lines/2;
595 scrolldelta(-lines);
598 voidscrollfront(int lines)
600 if(!lines)
601 lines = video_num_lines/2;
602 scrolldelta(lines);
605 static voidset_origin(int currcons)
607 if(video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_VGAC
608 && video_type != VIDEO_TYPE_EGAM)
609 return;
610 if(currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
611 return;
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;
620 if(t+nr >= b)
621 nr = b - t -1;
622 if(b > video_num_lines || t >= b || nr <1)
623 return;
624 if(t || b != video_num_lines || nr >1)
625 hardscroll =0;
626 if(hardscroll) {
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;
633 unsigned int count;
635 count = (video_num_lines-1)*video_num_columns;
636 while(count) {
637 count--;
638 scr_writew(scr_readw(s++),d++);
640 count = video_num_columns;
641 while(count) {
642 count--;
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;
648 has_scrolled =1;
649 if(currcons == fg_console)
650 has_wrapped =1;
651 }else{
652 unsigned short* d;
653 unsigned int count;
655 d = (unsigned short*) (scr_end - video_size_row);
656 count = video_num_columns;
657 while(count) {
658 count--;
659 scr_writew(video_erase_char, d++);
662 set_origin(currcons);
663 }else{
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);
672 static void
673 scrdown(int currcons,unsigned int t,unsigned int b,unsigned int nr)
675 unsigned short*s;
676 unsigned int count;
677 unsigned int step;
679 if(t+nr >= b)
680 nr = b - t -1;
681 if(b > video_num_lines || t >= b || nr <1)
682 return;
683 s = (unsigned short*) (origin+video_size_row*(b-nr-1));
684 step = video_num_columns * nr;
685 count = b - t - nr;
686 while(count--) {
687 memcpyw(s + step, s, video_size_row);
688 s -= video_num_columns;
690 while(nr--) {
691 s += video_num_columns;
692 memsetw(s, video_erase_char, video_size_row);
694 has_scrolled =1;
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.
705 void
706 scrreset(void)
708 int currcons = fg_console;
709 unsigned short* d = (unsigned short*) video_mem_start;
710 unsigned short* s = (unsigned short*) origin;
711 unsigned int count;
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;
721 has_scrolled =1;
722 has_wrapped =1;
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
733 if(y+1== bottom)
734 scrup(currcons,top,bottom,1);
735 else if(y < video_num_lines-1) {
736 y++;
737 pos += video_size_row;
739 need_wrap =0;
742 static voidri(int currcons)
744 /* don't scroll if below top of scrolling region, or
745 * if above scrolling region
747 if(y == top)
748 scrdown(currcons,top,bottom,1);
749 else if(y >0) {
750 y--;
751 pos -= video_size_row;
753 need_wrap =0;
756 staticinlinevoidcr(int currcons)
758 pos -= x<<1;
759 need_wrap = x =0;
762 staticinlinevoidbs(int currcons)
764 if(x) {
765 pos -=2;
766 x--;
767 need_wrap =0;
771 staticinlinevoiddel(int currcons)
773 /* ignored */
776 static voidcsi_J(int currcons,int vpar)
778 unsigned long count;
779 unsigned short* start;
781 switch(vpar) {
782 case0:/* erase from cursor to end of display */
783 count = (scr_end-pos)>>1;
784 start = (unsigned short*) pos;
785 break;
786 case1:/* erase from start to cursor */
787 count = ((pos-origin)>>1)+1;
788 start = (unsigned short*) origin;
789 break;
790 case2:/* erase whole display */
791 count = video_num_columns * video_num_lines;
792 start = (unsigned short*) origin;
793 break;
794 default:
795 return;
797 memsetw(start, video_erase_char,2*count);
798 need_wrap =0;
801 static voidcsi_K(int currcons,int vpar)
803 unsigned long count;
804 unsigned short* start;
806 switch(vpar) {
807 case0:/* erase from cursor to end of line */
808 count = video_num_columns-x;
809 start = (unsigned short*) pos;
810 break;
811 case1:/* erase from start of line to cursor */
812 start = (unsigned short*) (pos - (x<<1));
813 count = x+1;
814 break;
815 case2:/* erase whole line */
816 start = (unsigned short*) (pos - (x<<1));
817 count = video_num_columns;
818 break;
819 default:
820 return;
822 memsetw(start, video_erase_char,2* count);
823 need_wrap =0;
826 static voidcsi_X(int currcons,int vpar)/* erase the following vpar positions */
827 {/* not vt100? */
828 if(!vpar)
829 vpar++;
831 memsetw((unsigned short*) pos, video_erase_char,
832 (vpar > video_num_columns-x) ?2* (video_num_columns-x) :2* vpar);
833 need_wrap =0;
836 static voidupdate_attr(int currcons)
838 attr = color;
839 if(can_do_color) {
840 if(underline)
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);
847 if(blink)
848 attr ^=0x80;
849 if(intensity ==2)
850 attr ^=0x08;
851 if(!can_do_color) {
852 if(underline)
853 attr = (attr &0xf8) |0x01;
854 else if(intensity ==0)
855 attr = (attr &0xf0) |0x08;
857 if(decscnm)
858 video_erase_char = (reverse_video_char(color) <<8) |' ';
859 else
860 video_erase_char = (color <<8) |' ';
863 static voiddefault_attr(int currcons)
865 intensity =1;
866 underline =0;
867 reverse =0;
868 blink =0;
869 color = def_color;
872 static voidcsi_m(int currcons)
874 int i;
876 for(i=0;i<=npar;i++)
877 switch(par[i]) {
878 case0:/* all attributes off */
879 default_attr(currcons);
880 break;
881 case1:
882 intensity =2;
883 break;
884 case2:
885 intensity =0;
886 break;
887 case4:
888 underline =1;
889 break;
890 case5:
891 blink =1;
892 break;
893 case7:
894 reverse =1;
895 break;
896 case10:/* ANSI X3.64-1979 (SCO-ish?)
897 * Select primary font, don't display
898 * control chars if defined, don't set
899 * bit 8 on output.
901 translate =set_translate(charset ==0
902 ? G0_charset
903 : G1_charset);
904 disp_ctrl =0;
905 toggle_meta =0;
906 break;
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);
912 disp_ctrl =1;
913 toggle_meta =0;
914 break;
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);
920 disp_ctrl =1;
921 toggle_meta =1;
922 break;
923 case21:
924 case22:
925 intensity =1;
926 break;
927 case24:
928 underline =0;
929 break;
930 case25:
931 blink =0;
932 break;
933 case27:
934 reverse =0;
935 break;
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;
942 underline =1;
943 break;
944 case39:/* ANSI X3.64-1979 (SCO-ish?)
945 * Disable underline option.
946 * Reset colour to default? It did this
947 * before...
949 color = (def_color &0x0f) | background;
950 underline =0;
951 break;
952 case49:
953 color = (def_color &0xf0) | foreground;
954 break;
955 default:
956 if(par[i] >=30&& par[i] <=37)
957 color = color_table[par[i]-30]
958 | background;
959 else if(par[i] >=40&& par[i] <=47)
960 color = (color_table[par[i]-40]<<4)
961 | foreground;
962 break;
964 update_attr(currcons);
967 static voidrespond_string(const char* p,struct tty_struct * tty)
969 while(*p) {
970 tty_insert_flip_char(tty, *p,0);
971 p++;
973 tty_schedule_flip(tty);
976 static voidcursor_report(int currcons,struct tty_struct * tty)
978 char buf[40];
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)
996 char buf[8];
998 sprintf(buf,"\033[M%c%c%c", (char)(' '+ butt), (char)('!'+ mrx),
999 (char)('!'+ mry));
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)
1013 char type, data;
1015 if(tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
1016 return-EINVAL;
1017 if(current->tty != tty && !suser())
1018 return-EPERM;
1019 if(get_user(type, (char*)arg))
1020 return-EFAULT;
1021 switch(type)
1023 case2:
1024 returnset_selection(arg, tty,1);
1025 case3:
1026 returnpaste_selection(tty);
1027 case4:
1028 do_unblank_screen();
1029 return0;
1030 case5:
1031 returnsel_loadlut(arg);
1032 case6:
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.
1040 data = shift_state;
1041 return__put_user(data, (char*) arg);
1042 case7:
1043 data =mouse_reporting();
1044 return__put_user(data, (char*) arg);
1045 case10:
1046 set_vesa_blanking(arg);
1047 return0;
1048 case11:/* set kmsg redirect */
1049 if(!suser())
1050 return-EPERM;
1051 if(get_user(data, (char*)arg+1))
1052 return-EFAULT;
1053 kmsg_redirect = data;
1054 return0;
1055 case12:/* get fg_console */
1056 return fg_console;
1058 return-EINVAL;
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);
1066 return p;
1069 /* Note: inverting the screen twice should revert to the original state */
1070 voidinvert_screen(int currcons,int offset,int count,int viewed)
1072 unsigned short*p;
1074 count /=2;
1075 p =screenpos(currcons, offset, viewed);
1076 if(can_do_color)
1077 while(count--) {
1078 unsigned short old =scr_readw(p);
1079 scr_writew(reverse_video_short(old), p);
1080 p++;
1082 else
1083 while(count--) {
1084 unsigned short old =scr_readw(p);
1085 scr_writew(old ^ (((old &0x0700) ==0x0100)
1086 ?0x7000:0x7700), p);
1087 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;
1097 if(p)
1098 scr_writew(old, p);
1099 if(offset == -1)
1100 p = NULL;
1101 else{
1102 p =screenpos(currcons, offset,1);
1103 old =scr_readw(p);
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)
1119 : 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)
1130 p[0] = x;
1131 p[1] = y;
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)
1142 int i;
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 */
1147 if(on_off)
1148 set_kbd(decckm);
1149 else
1150 clr_kbd(decckm);
1151 break;
1152 case3:/* 80/132 mode switch unimplemented */
1153 deccolm = on_off;
1154 #if 0
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 */
1158 #endif
1159 break;
1160 case5:/* Inverted screen on/off */
1161 if(decscnm != on_off) {
1162 decscnm = on_off;
1163 invert_screen(currcons,0, video_screen_size,0);
1164 update_attr(currcons);
1166 break;
1167 case6:/* Origin relative/absolute */
1168 decom = on_off;
1169 gotoxay(currcons,0,0);
1170 break;
1171 case7:/* Autowrap on/off */
1172 decawm = on_off;
1173 break;
1174 case8:/* Autorepeat on/off */
1175 if(on_off)
1176 set_kbd(decarm);
1177 else
1178 clr_kbd(decarm);
1179 break;
1180 case9:
1181 report_mouse = on_off ?1:0;
1182 break;
1183 case25:/* Cursor on/off */
1184 deccm = on_off;
1185 set_cursor(currcons);
1186 break;
1187 case1000:
1188 report_mouse = on_off ?2:0;
1189 break;
1190 }else switch(par[i]) {/* ANSI modes set/reset */
1191 case3:/* Monitor (display ctrls) */
1192 disp_ctrl = on_off;
1193 break;
1194 case4:/* Insert Mode on/off */
1195 decim = on_off;
1196 break;
1197 case20:/* Lf, Enter == CrLf/Lf */
1198 if(on_off)
1199 set_kbd(lnm);
1200 else
1201 clr_kbd(lnm);
1202 break;
1206 static voidsetterm_command(int currcons)
1208 switch(par[0]) {
1209 case1:/* set color for underline mode */
1210 if(can_do_color && par[1] <16) {
1211 ulcolor = color_table[par[1]];
1212 if(underline)
1213 update_attr(currcons);
1215 break;
1216 case2:/* set color for half intensity mode */
1217 if(can_do_color && par[1] <16) {
1218 halfcolor = color_table[par[1]];
1219 if(intensity ==0)
1220 update_attr(currcons);
1222 break;
1223 case8:/* store colors as defaults */
1224 def_color = attr;
1225 default_attr(currcons);
1226 update_attr(currcons);
1227 break;
1228 case9:/* set blanking interval */
1229 blankinterval = ((par[1] <60) ? par[1] :60) *60* HZ;
1230 poke_blanked_console();
1231 break;
1232 case10:/* set bell frequency in Hz */
1233 if(npar >=1)
1234 bell_pitch = par[1];
1235 else
1236 bell_pitch = DEFAULT_BELL_PITCH;
1237 break;
1238 case11:/* set bell duration in msec */
1239 if(npar >=1)
1240 bell_duration = (par[1] <2000) ?
1241 par[1]*HZ/1000:0;
1242 else
1243 bell_duration = DEFAULT_BELL_DURATION;
1244 break;
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);
1248 break;
1249 case13:/* unblank the screen */
1250 unblank_screen();
1251 break;
1252 case14:/* set vesa powerdown interval */
1253 vesa_off_interval = ((par[1] <60) ? par[1] :60) *60* HZ;
1254 break;
1258 static voidinsert_char(int currcons)
1260 unsigned int i = x;
1261 unsigned short tmp, old = video_erase_char;
1262 unsigned short* p = (unsigned short*) pos;
1264 while(i++ < video_num_columns) {
1265 tmp =scr_readw(p);
1266 scr_writew(old, p);
1267 old = tmp;
1268 p++;
1270 need_wrap =0;
1273 static voidinsert_line(int currcons,unsigned int nr)
1275 scrdown(currcons,y,bottom,nr);
1276 need_wrap =0;
1279 static voiddelete_char(int currcons)
1281 unsigned int i = x;
1282 unsigned short* p = (unsigned short*) pos;
1284 while(++i < video_num_columns) {
1285 scr_writew(scr_readw(p+1), p);
1286 p++;
1288 scr_writew(video_erase_char, p);
1289 need_wrap =0;
1292 static voiddelete_line(int currcons,unsigned int nr)
1294 scrup(currcons,y,bottom,nr);
1295 need_wrap =0;
1298 static voidcsi_at(int currcons,unsigned int nr)
1300 if(nr > video_num_columns)
1301 nr = video_num_columns;
1302 else if(!nr)
1303 nr =1;
1304 while(nr--)
1305 insert_char(currcons);
1308 static voidcsi_L(int currcons,unsigned int nr)
1310 if(nr > video_num_lines)
1311 nr = video_num_lines;
1312 else if(!nr)
1313 nr =1;
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;
1321 else if(!nr)
1322 nr =1;
1323 while(nr--)
1324 delete_char(currcons);
1327 static voidcsi_M(int currcons,unsigned int nr)
1329 if(nr > video_num_lines)
1330 nr = video_num_lines;
1331 else if(!nr)
1332 nr=1;
1333 delete_line(currcons, nr);
1336 static voidsave_cur(int currcons)
1338 saved_x = x;
1339 saved_y = y;
1340 s_intensity = intensity;
1341 s_underline = underline;
1342 s_blink = blink;
1343 s_reverse = reverse;
1344 s_charset = charset;
1345 s_color = color;
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;
1355 blink = s_blink;
1356 reverse = s_reverse;
1357 charset = s_charset;
1358 color = s_color;
1359 G0_charset = saved_G0;
1360 G1_charset = saved_G1;
1361 translate =set_translate(charset ? G1_charset : G0_charset);
1362 update_attr(currcons);
1363 need_wrap =0;
1366 enum{ ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
1367 EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
1368 ESpalette };
1370 static voidreset_terminal(int currcons,int do_clear)
1372 top =0;
1373 bottom = video_num_lines;
1374 vc_state = ESnormal;
1375 ques =0;
1376 translate =set_translate(LAT1_MAP);
1377 G0_charset = LAT1_MAP;
1378 G1_charset = GRAF_MAP;
1379 charset =0;
1380 need_wrap =0;
1381 report_mouse =0;
1382 utf =0;
1383 utf_count =0;
1385 disp_ctrl =0;
1386 toggle_meta =0;
1388 decscnm =0;
1389 decom =0;
1390 decawm =1;
1391 deccm =1;
1392 decim =0;
1394 set_kbd(decarm);
1395 clr_kbd(decckm);
1396 clr_kbd(kbdapplic);
1397 clr_kbd(lnm);
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;
1402 set_leds();
1404 default_attr(currcons);
1405 update_attr(currcons);
1407 tab_stop[0] =0x01010100;
1408 tab_stop[1] =
1409 tab_stop[2] =
1410 tab_stop[3] =
1411 tab_stop[4] =0x01010101;
1413 bell_pitch = DEFAULT_BELL_PITCH;
1414 bell_duration = DEFAULT_BELL_DURATION;
1416 gotoxy(currcons,0,0);
1417 save_cur(currcons);
1418 if(do_clear)
1419 csi_J(currcons,2);
1423 * Turn the Scroll-Lock LED on when the tty is stopped
1425 static voidcon_stop(struct tty_struct *tty)
1427 int console_num;
1428 if(!tty)
1429 return;
1430 console_num =MINOR(tty->device) - (tty->driver.minor_start);
1431 if(!vc_cons_allocated(console_num))
1432 return;
1433 #if !CONFIG_AP1000
1434 set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1435 set_leds();
1436 #endif
1440 * Turn the Scroll-Lock LED off when the console is started
1442 static voidcon_start(struct tty_struct *tty)
1444 int console_num;
1445 if(!tty)
1446 return;
1447 console_num =MINOR(tty->device) - (tty->driver.minor_start);
1448 if(!vc_cons_allocated(console_num))
1449 return;
1450 #if !CONFIG_AP1000
1451 clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1452 set_leds();
1453 #endif
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;
1473 #if CONFIG_AP1000
1474 ap_write(1,buf,count);
1475 return(count);
1476 #endif
1478 currcons = vt->vc_num;
1479 if(!vc_cons_allocated(currcons)) {
1480 /* could this happen? */
1481 static int error =0;
1482 if(!error) {
1483 error =1;
1484 printk("con_write: tty %d not allocated\n", currcons+1);
1486 return0;
1489 if(currcons == sel_cons)
1490 clear_selection();
1492 if(from_user) {
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);
1501 if(from_user)
1502 __get_user(c, buf);
1503 else
1504 c = *buf;
1505 buf++; n++; count--;
1506 disable_bh(CONSOLE_BH);
1508 if(utf) {
1509 /* Combine UTF-8 into Unicode */
1510 /* Incomplete characters silently ignored */
1511 if(c >0x7f) {
1512 if(utf_count >0&& (c &0xc0) ==0x80) {
1513 utf_char = (utf_char <<6) | (c &0x3f);
1514 utf_count--;
1515 if(utf_count ==0)
1516 tc = c = utf_char;
1517 else continue;
1518 }else{
1519 if((c &0xe0) ==0xc0) {
1520 utf_count =1;
1521 utf_char = (c &0x1f);
1522 }else if((c &0xf0) ==0xe0) {
1523 utf_count =2;
1524 utf_char = (c &0x0f);
1525 }else if((c &0xf8) ==0xf0) {
1526 utf_count =3;
1527 utf_char = (c &0x07);
1528 }else if((c &0xfc) ==0xf8) {
1529 utf_count =4;
1530 utf_char = (c &0x03);
1531 }else if((c &0xfe) ==0xfc) {
1532 utf_count =5;
1533 utf_char = (c &0x01);
1534 }else
1535 utf_count =0;
1536 continue;
1538 }else{
1539 tc = c;
1540 utf_count =0;
1542 }else{/* no utf */
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)
1560 && (c !=128+27);
1562 if(vc_state == ESnormal && ok) {
1563 /* Now try to find out how to display it */
1564 tc =conv_uni_to_pc(tc);
1565 if( tc == -4) {
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. */
1573 if(tc == -4)
1574 tc = c;
1575 }else if( tc == -3) {
1576 /* Bad hash table -- hope for the best */
1577 tc = c;
1579 if(tc & ~console_charmask)
1580 continue;/* Conversion failed */
1582 if(need_wrap) {
1583 cr(currcons);
1584 lf(currcons);
1586 if(decim)
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)
1593 need_wrap = decawm;
1594 else{
1595 x++;
1596 pos+=2;
1598 continue;
1602 * Control characters can be used in the _middle_
1603 * of an escape sequence.
1605 switch(c) {
1606 case0:
1607 continue;
1608 case7:
1609 if(bell_duration)
1610 kd_mksound(bell_pitch, bell_duration);
1611 continue;
1612 case8:
1613 bs(currcons);
1614 continue;
1615 case9:
1616 pos -= (x <<1);
1617 while(x < video_num_columns -1) {
1618 x++;
1619 if(tab_stop[x >>5] & (1<< (x &31)))
1620 break;
1622 pos += (x <<1);
1623 continue;
1624 case10:case11:case12:
1625 lf(currcons);
1626 if(!is_kbd(lnm))
1627 continue;
1628 case13:
1629 cr(currcons);
1630 continue;
1631 case14:
1632 charset =1;
1633 translate =set_translate(G1_charset);
1634 disp_ctrl =1;
1635 continue;
1636 case15:
1637 charset =0;
1638 translate =set_translate(G0_charset);
1639 disp_ctrl =0;
1640 continue;
1641 case24:case26:
1642 vc_state = ESnormal;
1643 continue;
1644 case27:
1645 vc_state = ESesc;
1646 continue;
1647 case127:
1648 del(currcons);
1649 continue;
1650 case128+27:
1651 vc_state = ESsquare;
1652 continue;
1654 switch(vc_state) {
1655 case ESesc:
1656 vc_state = ESnormal;
1657 switch(c) {
1658 case'[':
1659 vc_state = ESsquare;
1660 continue;
1661 case']':
1662 vc_state = ESnonstd;
1663 continue;
1664 case'%':
1665 vc_state = ESpercent;
1666 continue;
1667 case'E':
1668 cr(currcons);
1669 lf(currcons);
1670 continue;
1671 case'M':
1672 ri(currcons);
1673 continue;
1674 case'D':
1675 lf(currcons);
1676 continue;
1677 case'H':
1678 tab_stop[x >>5] |= (1<< (x &31));
1679 continue;
1680 case'Z':
1681 respond_ID(tty);
1682 continue;
1683 case'7':
1684 save_cur(currcons);
1685 continue;
1686 case'8':
1687 restore_cur(currcons);
1688 continue;
1689 case'(':
1690 vc_state = ESsetG0;
1691 continue;
1692 case')':
1693 vc_state = ESsetG1;
1694 continue;
1695 case'#':
1696 vc_state = EShash;
1697 continue;
1698 case'c':
1699 reset_terminal(currcons,1);
1700 continue;
1701 case'>':/* Numeric keypad */
1702 clr_kbd(kbdapplic);
1703 continue;
1704 case'=':/* Appl. keypad */
1705 set_kbd(kbdapplic);
1706 continue;
1708 continue;
1709 case ESnonstd:
1710 if(c=='P') {/* palette escape sequence */
1711 for(npar=0; npar<NPAR; npar++)
1712 par[npar] =0;
1713 npar =0;
1714 vc_state = ESpalette;
1715 continue;
1716 }else if(c=='R') {/* reset palette */
1717 reset_palette(currcons);
1718 vc_state = ESnormal;
1719 }else
1720 vc_state = ESnormal;
1721 continue;
1722 case ESpalette:
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') ;
1725 if(npar==7) {
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];
1733 set_palette() ;
1734 vc_state = ESnormal;
1736 }else
1737 vc_state = ESnormal;
1738 continue;
1739 case ESsquare:
1740 for(npar =0; npar < NPAR ; npar++)
1741 par[npar] =0;
1742 npar =0;
1743 vc_state = ESgetpars;
1744 if(c =='[') {/* Function key */
1745 vc_state=ESfunckey;
1746 continue;
1748 ques = (c=='?');
1749 if(ques)
1750 continue;
1751 case ESgetpars:
1752 if(c==';'&& npar<NPAR-1) {
1753 npar++;
1754 continue;
1755 }else if(c>='0'&& c<='9') {
1756 par[npar] *=10;
1757 par[npar] += c-'0';
1758 continue;
1759 }else vc_state=ESgotpars;
1760 case ESgotpars:
1761 vc_state = ESnormal;
1762 switch(c) {
1763 case'h':
1764 set_mode(currcons,1);
1765 continue;
1766 case'l':
1767 set_mode(currcons,0);
1768 continue;
1769 case'n':
1770 if(!ques)
1771 if(par[0] ==5)
1772 status_report(tty);
1773 else if(par[0] ==6)
1774 cursor_report(currcons,tty);
1775 continue;
1777 if(ques) {
1778 ques =0;
1779 continue;
1781 switch(c) {
1782 case'G':case'`':
1783 if(par[0]) par[0]--;
1784 gotoxy(currcons,par[0],y);
1785 continue;
1786 case'A':
1787 if(!par[0]) par[0]++;
1788 gotoxy(currcons,x,y-par[0]);
1789 continue;
1790 case'B':case'e':
1791 if(!par[0]) par[0]++;
1792 gotoxy(currcons,x,y+par[0]);
1793 continue;
1794 case'C':case'a':
1795 if(!par[0]) par[0]++;
1796 gotoxy(currcons,x+par[0],y);
1797 continue;
1798 case'D':
1799 if(!par[0]) par[0]++;
1800 gotoxy(currcons,x-par[0],y);
1801 continue;
1802 case'E':
1803 if(!par[0]) par[0]++;
1804 gotoxy(currcons,0,y+par[0]);
1805 continue;
1806 case'F':
1807 if(!par[0]) par[0]++;
1808 gotoxy(currcons,0,y-par[0]);
1809 continue;
1810 case'd':
1811 if(par[0]) par[0]--;
1812 gotoxay(currcons,x,par[0]);
1813 continue;
1814 case'H':case'f':
1815 if(par[0]) par[0]--;
1816 if(par[1]) par[1]--;
1817 gotoxay(currcons,par[1],par[0]);
1818 continue;
1819 case'J':
1820 csi_J(currcons,par[0]);
1821 continue;
1822 case'K':
1823 csi_K(currcons,par[0]);
1824 continue;
1825 case'L':
1826 csi_L(currcons,par[0]);
1827 continue;
1828 case'M':
1829 csi_M(currcons,par[0]);
1830 continue;
1831 case'P':
1832 csi_P(currcons,par[0]);
1833 continue;
1834 case'c':
1835 if(!par[0])
1836 respond_ID(tty);
1837 continue;
1838 case'g':
1839 if(!par[0])
1840 tab_stop[x >>5] &= ~(1<< (x &31));
1841 else if(par[0] ==3) {
1842 tab_stop[0] =
1843 tab_stop[1] =
1844 tab_stop[2] =
1845 tab_stop[3] =
1846 tab_stop[4] =0;
1848 continue;
1849 case'm':
1850 csi_m(currcons);
1851 continue;
1852 case'q':/* DECLL - but only 3 leds */
1853 /* map 0,1,2,3 to 0,1,2,4 */
1854 if(par[0] <4)
1855 setledstate(kbd_table + currcons,
1856 (par[0] <3) ? par[0] :4);
1857 continue;
1858 case'r':
1859 if(!par[0])
1860 par[0]++;
1861 if(!par[1])
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) {
1866 top=par[0]-1;
1867 bottom=par[1];
1868 gotoxay(currcons,0,0);
1870 continue;
1871 case's':
1872 save_cur(currcons);
1873 continue;
1874 case'u':
1875 restore_cur(currcons);
1876 continue;
1877 case'X':
1878 csi_X(currcons, par[0]);
1879 continue;
1880 case'@':
1881 csi_at(currcons,par[0]);
1882 continue;
1883 case']':/* setterm functions */
1884 setterm_command(currcons);
1885 continue;
1887 continue;
1888 case ESpercent:
1889 vc_state = ESnormal;
1890 switch(c) {
1891 case'@':/* defined in ISO 2022 */
1892 utf =0;
1893 continue;
1894 case'G':/* prelim official escape code */
1895 case'8':/* retained for compatibility */
1896 utf =1;
1897 continue;
1899 continue;
1900 case ESfunckey:
1901 vc_state = ESnormal;
1902 continue;
1903 case EShash:
1904 vc_state = ESnormal;
1905 if(c =='8') {
1906 /* DEC screen alignment test. kludge :-) */
1907 video_erase_char =
1908 (video_erase_char &0xff00) |'E';
1909 csi_J(currcons,2);
1910 video_erase_char =
1911 (video_erase_char &0xff00) |' ';
1913 continue;
1914 case ESsetG0:
1915 if(c =='0')
1916 G0_charset = GRAF_MAP;
1917 else if(c =='B')
1918 G0_charset = LAT1_MAP;
1919 else if(c =='U')
1920 G0_charset = IBMPC_MAP;
1921 else if(c =='K')
1922 G0_charset = USER_MAP;
1923 if(charset ==0)
1924 translate =set_translate(G0_charset);
1925 vc_state = ESnormal;
1926 continue;
1927 case ESsetG1:
1928 if(c =='0')
1929 G1_charset = GRAF_MAP;
1930 else if(c =='B')
1931 G1_charset = LAT1_MAP;
1932 else if(c =='U')
1933 G1_charset = IBMPC_MAP;
1934 else if(c =='K')
1935 G1_charset = USER_MAP;
1936 if(charset ==1)
1937 translate =set_translate(G1_charset);
1938 vc_state = ESnormal;
1939 continue;
1940 default:
1941 vc_state = ESnormal;
1944 enable_bh(CONSOLE_BH);
1945 return n;
1948 static intcon_write(struct tty_struct * tty,int from_user,
1949 const unsigned char*buf,int count)
1951 int retval;
1953 retval =do_con_write(tty, from_user, buf, count);
1954 con_flush_chars(tty);
1956 return retval;
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)
1966 if(tty->stopped)
1967 return0;
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)
1980 return;
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;
1995 unsigned char c;
1996 static int printing =0;
1998 #if CONFIG_AP1000
1999 prom_printf(b);
2000 return;
2001 #endif
2002 if(!printable || printing)
2003 return;/* console not yet initialized */
2004 printing =1;
2006 if(kmsg_redirect &&vc_cons_allocated(kmsg_redirect -1))
2007 currcons = kmsg_redirect -1;
2009 if(!vc_cons_allocated(currcons)) {
2010 /* impossible */
2011 printk("vt_console_print: tty %d not allocated ??\n", currcons+1);
2012 return;
2015 #ifdef CONFIG_SERIAL_ECHO
2016 serial_echo_print(b);
2017 #endif/* CONFIG_SERIAL_ECHO */
2019 while(count-- >0) {
2020 c = *(b++);
2021 if(c ==10|| c ==13|| need_wrap) {
2022 if(c !=13)
2023 lf(currcons);
2024 cr(currcons);
2025 if(c ==10|| c ==13)
2026 continue;
2028 if(c ==8) {/* backspace */
2029 bs(currcons);
2030 continue;
2032 scr_writew((attr <<8) + c, (unsigned short*) pos);
2033 if(x == video_num_columns -1) {
2034 need_wrap =1;
2035 continue;
2037 x++;
2038 pos+=2;
2040 set_cursor(currcons);
2041 poke_blanked_console();
2042 printing =0;
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 = {
2053 "tty",
2054 vt_console_print,
2055 NULL,
2056 vt_console_device,
2057 keyboard_wait_for_keypress,
2058 do_unblank_screen,
2059 NULL,
2060 CON_PRINTBUFFER,
2063 NULL
2065 #endif
2068 * con_throttle and con_unthrottle are only used for
2069 * paste_selection(), which has to stuff in a large number of
2070 * characters...
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];
2086 int j, k ;
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;
2096 reset_vc(currcons);
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 */
2135 want_console = -1;
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 ="????";
2159 int currcons =0;
2160 int orig_x = ORIG_X;
2161 int orig_y = ORIG_Y;
2163 #ifdef __sparc__
2164 if(serial_console) {
2165 fg_console =0;
2167 #if CONFIG_SUN_SERIAL
2168 rs_cons_hook(0,0, serial_console);
2169 rs_cons_hook(0,1, serial_console);
2170 #endif
2172 return kmem_start;
2174 #endif
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");
2206 #if CONFIG_AP1000
2207 return(kmem_start);
2208 #endif
2209 con_setsize(ORIG_VIDEO_LINES, ORIG_VIDEO_COLS);
2211 timer_table[BLANK_TIMER].fn = blank_screen;
2212 timer_table[BLANK_TIMER].expires =0;
2213 if(blankinterval) {
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));
2224 has_wrapped =0;
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++) {
2229 int j, k ;
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;
2237 kmalloced =0;
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);
2255 csi_J(currcons,0);
2257 /* Figure out the size of the screen and screen font so we
2258 can figure out the appropriate screen size should we load
2259 a different font */
2261 printable =1;
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",
2282 MAX_NR_CONSOLES);
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);
2295 #endif
2297 init_bh(CONSOLE_BH, console_bh);
2298 return kmem_start;
2301 voidvesa_powerdown_screen(void)
2303 timer_active &= ~(1<<BLANK_TIMER);
2304 timer_table[BLANK_TIMER].fn = unblank_screen;
2306 vesa_powerdown();
2309 voiddo_blank_screen(int nopowersave)
2311 int currcons;
2313 if(console_blanked)
2314 return;
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);
2320 }else{
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;
2327 has_scrolled =0;
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);
2335 hide_cursor();
2336 console_blanked = fg_console +1;
2338 if(!nopowersave)
2340 #ifdef CONFIG_APM
2341 if(apm_display_blank())
2342 return;
2343 #endif
2344 vesa_blank();
2348 voiddo_unblank_screen(void)
2350 int currcons;
2351 int resetorg;
2352 long offset;
2354 if(!console_blanked)
2355 return;
2356 if(!vc_cons_allocated(fg_console)) {
2357 /* impossible */
2358 printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
2359 return;
2361 timer_table[BLANK_TIMER].fn = blank_screen;
2362 if(blankinterval) {
2363 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2364 timer_active |=1<<BLANK_TIMER;
2367 currcons = fg_console;
2368 offset =0;
2369 resetorg =0;
2370 if(console_blanked == fg_console +1&& origin == unblank_origin
2371 && !has_scrolled) {
2372 /* try to restore the exact situation before blanking */
2373 resetorg =1;
2374 offset = (blank_origin - video_mem_base)
2375 - (unblank_origin - video_mem_start);
2378 console_blanked =0;
2379 set_scrmem(fg_console, offset);
2380 set_origin(fg_console);
2381 set_cursor(fg_console);
2382 if(resetorg)
2383 __set_origin(blank__origin);
2385 vesa_unblank();
2386 #ifdef CONFIG_APM
2387 if(apm_display_unblank())
2388 return;
2389 #endif
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)
2398 do_blank_screen(0);
2401 static voidunblank_screen(void)
2403 do_unblank_screen();
2406 voidupdate_screen(int new_console)
2408 static int lock =0;
2410 if(new_console == fg_console || lock)
2411 return;
2412 if(!vc_cons_allocated(new_console)) {
2413 /* strange ... */
2414 printk("update_screen: tty %d not allocated ??\n", new_console+1);
2415 return;
2417 lock =1;
2419 clear_selection();
2421 if(!console_blanked)
2422 get_scrmem(fg_console);
2423 else
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);
2430 set_leds();
2431 compute_shiftstate();
2432 lock =0;
2436 * Allocate the console screen memory.
2438 static intcon_open(struct tty_struct *tty,struct file * filp)
2440 unsigned int idx;
2441 int i;
2443 idx =MINOR(tty->device) - tty->driver.minor_start;
2445 i =vc_allocate(idx);
2446 if(i)
2447 return i;
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;
2456 return0;
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)
2477 int j, k ;
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];
2483 set_palette() ;
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)
2494 int i;
2496 i =set_get_font(arg,1,ch512);
2497 if( !i ) {
2498 hashtable_contents_valid =0;
2499 video_mode_512ch = ch512;
2500 console_charmask = ch512 ?0x1ff:0x0ff;
2502 return i;
2505 intcon_get_font(char*arg)
2507 returnset_get_font(arg,0,video_mode_512ch);
close