This source file includes following definitions.
- serial_echo_print
- serial_echo_init
- vc_cons_allocated
- vc_allocate
- vc_resize
- vc_disallocate
- gotoxy
- scrollback
- scrollfront
- set_origin
- scrup
- scrdown
- lf
- ri
- cr
- bs
- del
- csi_J
- csi_K
- csi_X
- update_attr
- default_attr
- csi_m
- respond_string
- cursor_report
- status_report
- respond_ID
- mouse_report
- mouse_reporting
- screenpos
- invert_screen
- complement_pos
- screen_word
- scrw2glyph
- screen_pos
- getconsxy
- putconsxy
- set_mode
- setterm_command
- insert_char
- insert_line
- delete_char
- delete_line
- csi_at
- csi_L
- csi_P
- csi_M
- save_cur
- restore_cur
- reset_terminal
- con_stop
- con_start
- con_write
- con_write_room
- con_chars_in_buffer
- poke_blanked_console
- console_print
- con_throttle
- con_unthrottle
- vc_init
- con_setsize
- console_bh
- con_init
- vesa_powerdown_screen
- do_blank_screen
- do_unblank_screen
- blank_screen
- unblank_screen
- update_screen
- con_open
- con_set_cmap
- con_get_cmap
- reset_palette
- con_set_font
- con_get_font
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 #define BLANK 0x0020
66
67
68
69
70
71
72 #define CTRL_ACTION 0x0d00ff81
73 #define CTRL_ALWAYS 0x0800f501
74
75
76
77
78 #define DEFAULT_BELL_PITCH 750
79 #define DEFAULT_BELL_DURATION (HZ/8)
80
81
82
83
84
85
86
87
88 #include <linux/sched.h>
89 #include <linux/timer.h>
90 #include <linux/interrupt.h>
91 #include <linux/tty.h>
92 #include <linux/tty_flip.h>
93 #include <linux/config.h>
94 #include <linux/kernel.h>
95 #include <linux/string.h>
96 #include <linux/errno.h>
97 #include <linux/kd.h>
98 #include <linux/malloc.h>
99 #include <linux/major.h>
100 #include <linux/mm.h>
101 #include <linux/ioport.h>
102 #ifdef CONFIG_APM
103 #include <linux/apm_bios.h>
104 #endif
105
106 #include <asm/io.h>
107 #include <asm/system.h>
108 #include <asm/segment.h>
109 #include <asm/bitops.h>
110
111 #include "kbd_kern.h"
112 #include "vt_kern.h"
113 #include "consolemap.h"
114 #include "selection.h"
115 #include "console_struct.h"
116
117 #ifndef MIN
118 #define MIN(a,b) ((a) < (b) ? (a) : (b))
119 #endif
120
121 struct tty_driver console_driver;
122 static int console_refcount;
123 static struct tty_struct *console_table[MAX_NR_CONSOLES];
124 static struct termios *console_termios[MAX_NR_CONSOLES];
125 static struct termios *console_termios_locked[MAX_NR_CONSOLES];
126
127 static void con_setsize(unsigned long rows, unsigned long cols);
128 static void vc_init(unsigned int console, unsigned long rows,
129 unsigned long cols, int do_clear);
130 extern void get_scrmem(int currcons);
131 extern void set_scrmem(int currcons, long offset);
132 static void set_origin(int currcons);
133 static void blank_screen(void);
134 static void unblank_screen(void);
135 extern void change_console(unsigned int);
136 extern void poke_blanked_console(void);
137 static void gotoxy(int currcons, int new_x, int new_y);
138 static void save_cur(int currcons);
139 extern void set_cursor(int currcons);
140 extern void hide_cursor(void);
141 static void reset_terminal(int currcons, int do_clear);
142 extern void reset_vc(unsigned int new_console);
143 extern void vt_init(void);
144 extern void register_console(void (*proc)(const char *));
145 extern void vesa_blank(void);
146 extern void vesa_unblank(void);
147 extern void vesa_powerdown(void);
148 extern void compute_shiftstate(void);
149 extern void reset_palette(int currcons);
150 extern void set_palette(void);
151 extern unsigned long con_type_init(unsigned long, const char **);
152 extern int set_get_cmap(unsigned char *, int);
153 extern int set_get_font(unsigned char *, int, int);
154
155
156
157 unsigned char video_type;
158 unsigned long video_mem_base;
159 unsigned long video_mem_term;
160 static unsigned char video_page;
161
162 unsigned short video_port_reg;
163 unsigned short video_port_val;
164
165 unsigned long video_num_columns;
166 unsigned long video_num_lines;
167 unsigned long video_size_row;
168 unsigned long video_screen_size;
169 int can_do_color = 0;
170 static int printable = 0;
171
172 int video_mode_512ch = 0;
173 unsigned long video_font_height;
174 unsigned long video_scan_lines;
175 unsigned long default_font_height;
176 int video_font_is_default = 1;
177 static unsigned short console_charmask = 0x0ff;
178
179 unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
180
181
182 int do_poke_blanked_console = 0;
183 int console_blanked = 0;
184 static int blankinterval = 10*60*HZ;
185 static int vesa_off_interval = 0;
186 static long blank_origin, blank__origin, unblank_origin;
187
188 struct vc vc_cons [MAX_NR_CONSOLES];
189
190
191 #ifdef CONFIG_SERIAL_ECHO
192
193 #include <linux/serial_reg.h>
194
195 extern int serial_echo_init (int base);
196 extern int serial_echo_print (const char *s);
197
198
199
200
201
202 #define SERIAL_ECHO_PORT 0x3f8
203
204 static int serial_echo_port = 0;
205
206 #define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port)
207 #define serial_echo_inb(a) inb((a)+serial_echo_port)
208
209 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
210
211
212 #define WAIT_FOR_XMITR \
213 do { \
214 lsr = serial_echo_inb(UART_LSR); \
215 } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
216
217
218
219
220
221 int
222 serial_echo_print(const char *s)
223 {
224 int lsr, ier;
225 int i;
226
227 if (!serial_echo_port) return (0);
228
229
230
231
232 ier = serial_echo_inb(UART_IER);
233 serial_echo_outb(0x00, UART_IER);
234
235
236
237
238 for (i = 0; *s; i++, s++) {
239 WAIT_FOR_XMITR;
240
241
242 serial_echo_outb(*s, UART_TX);
243
244
245 if (*s == 10) {
246 WAIT_FOR_XMITR;
247 serial_echo_outb(13, UART_TX);
248 }
249 }
250
251
252
253
254
255 do {
256 lsr = serial_echo_inb(UART_LSR);
257 } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
258 serial_echo_outb(ier, UART_IER);
259
260 return (0);
261 }
262
263
264 int
265 serial_echo_init(int base)
266 {
267 int comstat, hi, lo;
268
269 if (base != 0x2f8 && base != 0x3f8) {
270 serial_echo_port = 0;
271 return (0);
272 } else
273 serial_echo_port = base;
274
275
276
277
278 comstat = serial_echo_inb(UART_LCR);
279 serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR);
280 hi = serial_echo_inb(UART_DLM);
281 lo = serial_echo_inb(UART_DLL);
282 serial_echo_outb(comstat, UART_LCR);
283
284
285
286
287 serial_echo_outb(0x03, UART_LCR);
288 serial_echo_outb(0x83, UART_LCR);
289 serial_echo_outb(0x00, UART_DLM);
290 serial_echo_outb(0x0c, UART_DLL);
291 serial_echo_outb(0x03, UART_LCR);
292
293
294
295
296 comstat = serial_echo_inb(UART_LSR);
297 comstat = serial_echo_inb(UART_RX);
298 serial_echo_outb(0x00, UART_IER);
299
300 return(0);
301 }
302
303 #endif
304
305
306 int vc_cons_allocated(unsigned int i)
307 {
308 return (i < MAX_NR_CONSOLES && vc_cons[i].d);
309 }
310
311 int vc_allocate(unsigned int i)
312 {
313 if (i >= MAX_NR_CONSOLES)
314 return -ENODEV;
315 if (!vc_cons[i].d) {
316 long p, q;
317
318
319 if (i >= MAX_NR_USER_CONSOLES && !suser())
320 return -EPERM;
321
322
323
324
325 q = (long) kmalloc(video_screen_size, GFP_KERNEL);
326 if (!q)
327 return -ENOMEM;
328 p = (long) kmalloc(structsize, GFP_KERNEL);
329 if (!p) {
330 kfree_s((char *) q, video_screen_size);
331 return -ENOMEM;
332 }
333
334 vc_cons[i].d = (struct vc_data *) p;
335 p += sizeof(struct vc_data);
336 vt_cons[i] = (struct vt_struct *) p;
337 vc_scrbuf[i] = (unsigned short *) q;
338 vc_cons[i].d->vc_kmalloced = 1;
339 vc_cons[i].d->vc_screenbuf_size = video_screen_size;
340 vc_init (i, video_num_lines, video_num_columns, 1);
341 }
342 return 0;
343 }
344
345
346
347
348
349
350 int vc_resize(unsigned long lines, unsigned long cols)
351 {
352 unsigned long cc, ll, ss, sr;
353 unsigned long occ, oll, oss, osr;
354 unsigned short *p;
355 unsigned int currcons, i;
356 unsigned short *newscreens[MAX_NR_CONSOLES];
357 long ol, nl, rlth, rrem;
358
359 cc = (cols ? cols : video_num_columns);
360 ll = (lines ? lines : video_num_lines);
361 sr = cc << 1;
362 ss = sr * ll;
363
364 if (ss > video_mem_term - video_mem_base)
365 return -ENOMEM;
366
367
368
369
370
371
372
373 for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
374 if (!vc_cons_allocated(currcons))
375 newscreens[currcons] = 0;
376 else {
377 p = (unsigned short *) kmalloc(ss, GFP_USER);
378 if (!p) {
379 for (i = 0; i< currcons; i++)
380 if (newscreens[i])
381 kfree_s(newscreens[i], ss);
382 return -ENOMEM;
383 }
384 newscreens[currcons] = p;
385 }
386 }
387
388 get_scrmem(fg_console);
389
390 oll = video_num_lines;
391 occ = video_num_columns;
392 osr = video_size_row;
393 oss = video_screen_size;
394
395 video_num_lines = ll;
396 video_num_columns = cc;
397 video_size_row = sr;
398 video_screen_size = ss;
399
400 for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
401 if (!vc_cons_allocated(currcons))
402 continue;
403
404 rlth = MIN(osr, sr);
405 rrem = sr - rlth;
406 ol = origin;
407 nl = (long) newscreens[currcons];
408 if (ll < oll)
409 ol += (oll - ll) * osr;
410
411 while (ol < scr_end) {
412 memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
413 if (rrem)
414 memsetw((void *)(nl + rlth), video_erase_char, rrem);
415 ol += osr;
416 nl += sr;
417 }
418
419 if (kmalloced)
420 kfree_s(vc_scrbuf[currcons], screenbuf_size);
421 vc_scrbuf[currcons] = newscreens[currcons];
422 kmalloced = 1;
423 screenbuf_size = ss;
424
425 origin = video_mem_start = (long) vc_scrbuf[currcons];
426 scr_end = video_mem_end = video_mem_start + ss;
427
428 if (scr_end > nl)
429 memsetw((void *) nl, video_erase_char, scr_end - nl);
430
431
432 top = 0;
433 bottom = video_num_lines;
434 gotoxy(currcons, x, y);
435 save_cur(currcons);
436 }
437
438 set_scrmem(fg_console, 0);
439 set_origin(fg_console);
440 set_cursor(fg_console);
441
442 return 0;
443 }
444
445 void vc_disallocate(unsigned int currcons)
446 {
447 if (vc_cons_allocated(currcons)) {
448 if (kmalloced)
449 kfree_s(vc_scrbuf[currcons], screenbuf_size);
450 if (currcons >= MIN_NR_CONSOLES)
451 kfree_s(vc_cons[currcons].d, structsize);
452 vc_cons[currcons].d = 0;
453 }
454 }
455
456
457 #define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
458 #define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
459 #define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
460
461 #define decarm VC_REPEAT
462 #define decckm VC_CKMODE
463 #define kbdapplic VC_APPLIC
464 #define lnm VC_CRLF
465
466
467
468
469 #define VT100ID "\033[?1;2c"
470 #define VT102ID "\033[?6c"
471
472 unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
473 8,12,10,14, 9,13,11,15 };
474
475
476 int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
477 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
478 int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
479 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
480 int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
481 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
482
483
484
485
486
487
488 static void gotoxy(int currcons, int new_x, int new_y)
489 {
490 int max_y;
491
492 if (new_x < 0)
493 x = 0;
494 else
495 if (new_x >= video_num_columns)
496 x = video_num_columns - 1;
497 else
498 x = new_x;
499 if (decom) {
500 new_y += top;
501 max_y = bottom;
502 } else
503 max_y = video_num_lines;
504 if (new_y < 0)
505 y = 0;
506 else
507 if (new_y >= max_y)
508 y = max_y - 1;
509 else
510 y = new_y;
511 pos = origin + y*video_size_row + (x<<1);
512 need_wrap = 0;
513 }
514
515
516
517
518 unsigned short __real_origin;
519 unsigned short __origin;
520 #define last_lpos (((video_mem_term-video_mem_base)/video_num_columns/2)-video_num_lines+1)
521 #define last_origin_rel ( last_lpos * video_num_columns )
522 #define last_origin ( video_mem_base + last_origin_rel * 2 )
523 unsigned short __scrollback_mode;
524 extern void __set_origin(unsigned short);
525
526 void scrollback(int lines)
527 {
528 if (!lines)
529 lines = video_num_lines/2;
530 lines *= video_num_columns;
531 lines = __origin - lines;
532 if (__scrollback_mode == 0) {
533 if (lines < 0)
534 lines = 0;
535 } else {
536 int s_top = __real_origin+video_num_lines*video_num_columns ;
537 if (lines < 0) {
538 int count ;
539 unsigned short * d = (unsigned short *) video_mem_base;
540 unsigned short * s = (unsigned short *) last_origin;
541
542 lines += last_origin_rel;
543
544
545 count = (video_num_lines-1)*video_num_columns;
546 while (count) {
547 count--;
548 scr_writew(scr_readw(d++),s++);
549 }
550 } else if (__origin > __real_origin && lines < s_top)
551 lines = s_top ;
552 }
553 __set_origin(lines);
554 }
555
556 void scrollfront(int lines)
557 {
558 if (!lines)
559 lines = video_num_lines/2;
560 lines *= video_num_columns;
561 if (__origin > __real_origin) {
562
563 lines += __origin;
564 if (lines >= last_origin_rel) {
565 lines -= last_origin_rel ;
566 if (lines > __real_origin)
567 lines = __real_origin;
568 }
569 } else {
570 lines += __origin;
571 if (lines > __real_origin)
572 lines = __real_origin;
573 }
574 __set_origin(lines);
575 }
576
577 static void set_origin(int currcons)
578 {
579 if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_VGAC
580 && video_type != VIDEO_TYPE_EGAM)
581 return;
582 if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
583 return;
584 __real_origin = (origin-video_mem_base) >> 1;
585 __set_origin(__real_origin);
586 }
587
588 void scrup(int currcons, unsigned int t, unsigned int b)
589 {
590 int hardscroll = 1;
591
592 if (b > video_num_lines || t >= b)
593 return;
594 if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_VGAC
595 && video_type != VIDEO_TYPE_EGAM)
596 hardscroll = 0;
597 else if (t || b != video_num_lines)
598 hardscroll = 0;
599 if (hardscroll) {
600 origin += video_size_row;
601 pos += video_size_row;
602 scr_end += video_size_row;
603 if (origin >= last_origin) {
604 unsigned short * d = (unsigned short *) video_mem_start;
605 unsigned short * s = (unsigned short *) origin;
606 unsigned int count;
607
608 count = (video_num_lines-1)*video_num_columns;
609 while (count) {
610 count--;
611 scr_writew(scr_readw(s++),d++);
612 }
613 count = video_num_columns;
614 while (count) {
615 count--;
616 scr_writew(video_erase_char, d++);
617 }
618 scr_end -= origin-video_mem_start;
619 pos -= origin-video_mem_start;
620 origin = video_mem_start;
621 has_scrolled = 1;
622 if (currcons == fg_console)
623 __scrollback_mode = 1;
624 } else {
625 unsigned short * d;
626 unsigned int count;
627
628 d = (unsigned short *) (scr_end - video_size_row);
629 count = video_num_columns;
630 while (count) {
631 count--;
632 scr_writew(video_erase_char, d++);
633 }
634 if (scr_end > last_origin)
635 __scrollback_mode = 0;
636 }
637 set_origin(currcons);
638 } else {
639 unsigned short * d = (unsigned short *) (origin+video_size_row*t);
640 unsigned short * s = (unsigned short *) (origin+video_size_row*(t+1));
641 unsigned int count = (b-t-1) * video_num_columns;
642
643 while (count) {
644 count--;
645 scr_writew(scr_readw(s++), d++);
646 }
647 count = video_num_columns;
648 while (count) {
649 count--;
650 scr_writew(video_erase_char, d++);
651 }
652 }
653 }
654
655 void
656 scrdown(int currcons, unsigned int t, unsigned int b)
657 {
658 unsigned short *d, *s;
659 unsigned int count;
660
661 if (b > video_num_lines || t >= b)
662 return;
663 d = (unsigned short *) (origin+video_size_row*b);
664 s = (unsigned short *) (origin+video_size_row*(b-1));
665 count = (b-t-1)*video_num_columns;
666 while (count) {
667 count--;
668 scr_writew(scr_readw(--s), --d);
669 }
670 count = video_num_columns;
671 while (count) {
672 count--;
673 scr_writew(video_erase_char, --d);
674 }
675 has_scrolled = 1;
676 }
677
678 static void lf(int currcons)
679 {
680
681
682
683 if (y+1 == bottom)
684 scrup(currcons,top,bottom);
685 else if (y < video_num_lines-1) {
686 y++;
687 pos += video_size_row;
688 }
689 need_wrap = 0;
690 }
691
692 static void ri(int currcons)
693 {
694
695
696
697 if (y == top)
698 scrdown(currcons,top,bottom);
699 else if (y > 0) {
700 y--;
701 pos -= video_size_row;
702 }
703 need_wrap = 0;
704 }
705
706 static inline void cr(int currcons)
707 {
708 pos -= x<<1;
709 need_wrap = x = 0;
710 }
711
712 static inline void bs(int currcons)
713 {
714 if (x) {
715 pos -= 2;
716 x--;
717 need_wrap = 0;
718 }
719 }
720
721 static inline void del(int currcons)
722 {
723
724 }
725
726 static void csi_J(int currcons, int vpar)
727 {
728 unsigned long count;
729 unsigned short * start;
730
731 switch (vpar) {
732 case 0:
733 count = (scr_end-pos)>>1;
734 start = (unsigned short *) pos;
735 break;
736 case 1:
737 count = ((pos-origin)>>1)+1;
738 start = (unsigned short *) origin;
739 break;
740 case 2:
741 count = video_num_columns * video_num_lines;
742 start = (unsigned short *) origin;
743 break;
744 default:
745 return;
746 }
747 while (count) {
748 count--;
749 scr_writew(video_erase_char, start++);
750 }
751 need_wrap = 0;
752 }
753
754 static void csi_K(int currcons, int vpar)
755 {
756 unsigned long count;
757 unsigned short * start;
758
759 switch (vpar) {
760 case 0:
761 count = video_num_columns-x;
762 start = (unsigned short *) pos;
763 break;
764 case 1:
765 start = (unsigned short *) (pos - (x<<1));
766 count = x+1;
767 break;
768 case 2:
769 start = (unsigned short *) (pos - (x<<1));
770 count = video_num_columns;
771 break;
772 default:
773 return;
774 }
775 while (count) {
776 count--;
777 scr_writew(video_erase_char, start++);
778 }
779 need_wrap = 0;
780 }
781
782 static void csi_X(int currcons, int vpar)
783 {
784 unsigned long count;
785 unsigned short * start;
786
787 if (!vpar)
788 vpar++;
789
790 start = (unsigned short *) pos;
791 count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
792
793 while (count) {
794 count--;
795 scr_writew(video_erase_char, start++);
796 }
797 need_wrap = 0;
798 }
799
800 static void update_attr(int currcons)
801 {
802 attr = color;
803 if (can_do_color) {
804 if (underline)
805 attr = (attr & 0xf0) | ulcolor;
806 else if (intensity == 0)
807 attr = (attr & 0xf0) | halfcolor;
808 }
809 if (reverse ^ decscnm)
810 attr = reverse_video_char(attr);
811 if (blink)
812 attr ^= 0x80;
813 if (intensity == 2)
814 attr ^= 0x08;
815 if (!can_do_color) {
816 if (underline)
817 attr = (attr & 0xf8) | 0x01;
818 else if (intensity == 0)
819 attr = (attr & 0xf0) | 0x08;
820 }
821 if (decscnm)
822 video_erase_char = (reverse_video_char(color) << 8) | ' ';
823 else
824 video_erase_char = (color << 8) | ' ';
825 }
826
827 static void default_attr(int currcons)
828 {
829 intensity = 1;
830 underline = 0;
831 reverse = 0;
832 blink = 0;
833 color = def_color;
834 }
835
836 static void csi_m(int currcons)
837 {
838 int i;
839
840 for (i=0;i<=npar;i++)
841 switch (par[i]) {
842 case 0:
843 default_attr(currcons);
844 break;
845 case 1:
846 intensity = 2;
847 break;
848 case 2:
849 intensity = 0;
850 break;
851 case 4:
852 underline = 1;
853 break;
854 case 5:
855 blink = 1;
856 break;
857 case 7:
858 reverse = 1;
859 break;
860 case 10:
861
862
863
864
865 translate = set_translate(charset == 0
866 ? G0_charset
867 : G1_charset);
868 disp_ctrl = 0;
869 toggle_meta = 0;
870 break;
871 case 11:
872
873
874
875 translate = set_translate(IBMPC_MAP);
876 disp_ctrl = 1;
877 toggle_meta = 0;
878 break;
879 case 12:
880
881
882
883 translate = set_translate(IBMPC_MAP);
884 disp_ctrl = 1;
885 toggle_meta = 1;
886 break;
887 case 21:
888 case 22:
889 intensity = 1;
890 break;
891 case 24:
892 underline = 0;
893 break;
894 case 25:
895 blink = 0;
896 break;
897 case 27:
898 reverse = 0;
899 break;
900 case 38:
901
902
903
904
905 color = (def_color & 0x0f) | background;
906 underline = 1;
907 break;
908 case 39:
909
910
911
912
913 color = (def_color & 0x0f) | background;
914 underline = 0;
915 break;
916 case 49:
917 color = (def_color & 0xf0) | foreground;
918 break;
919 default:
920 if (par[i] >= 30 && par[i] <= 37)
921 color = color_table[par[i]-30]
922 | background;
923 else if (par[i] >= 40 && par[i] <= 47)
924 color = (color_table[par[i]-40]<<4)
925 | foreground;
926 break;
927 }
928 update_attr(currcons);
929 }
930
931 static void respond_string(const char * p, struct tty_struct * tty)
932 {
933 while (*p) {
934 tty_insert_flip_char(tty, *p, 0);
935 p++;
936 }
937 tty_schedule_flip(tty);
938 }
939
940 static void cursor_report(int currcons, struct tty_struct * tty)
941 {
942 char buf[40];
943
944 sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
945 respond_string(buf, tty);
946 }
947
948 static inline void status_report(struct tty_struct * tty)
949 {
950 respond_string("\033[0n", tty);
951 }
952
953 static inline void respond_ID(struct tty_struct * tty)
954 {
955 respond_string(VT102ID, tty);
956 }
957
958 void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
959 {
960 char buf[8];
961
962 sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
963 (char)('!' + mry));
964 respond_string(buf, tty);
965 }
966
967
968 int mouse_reporting(void)
969 {
970 int currcons = fg_console;
971
972 return report_mouse;
973 }
974
975 static inline unsigned short *screenpos(int currcons, int offset, int viewed)
976 {
977 unsigned short *p = (unsigned short *)(origin + offset);
978 if (viewed && currcons == fg_console)
979 p -= (__real_origin - __origin);
980 return p;
981 }
982
983
984 void invert_screen(int currcons, int offset, int count, int viewed)
985 {
986 unsigned short *p;
987
988 count /= 2;
989 p = screenpos(currcons, offset, viewed);
990 if (can_do_color)
991 while (count--) {
992 unsigned short old = scr_readw(p);
993 scr_writew(reverse_video_short(old), p);
994 p++;
995 }
996 else
997 while (count--) {
998 unsigned short old = scr_readw(p);
999 scr_writew(old ^ (((old & 0x0700) == 0x0100)
1000 ? 0x7000 : 0x7700), p);
1001 p++;
1002 }
1003 }
1004
1005
1006 void complement_pos(int currcons, int offset)
1007 {
1008 static unsigned short *p = NULL;
1009 static unsigned short old = 0;
1010
1011 if (p)
1012 scr_writew(old, p);
1013 if (offset == -1)
1014 p = NULL;
1015 else {
1016 p = screenpos(currcons, offset, 1);
1017 old = scr_readw(p);
1018 scr_writew(old ^ 0x7700, p);
1019 }
1020 }
1021
1022
1023 unsigned short screen_word(int currcons, int offset, int viewed)
1024 {
1025 return scr_readw(screenpos(currcons, offset, viewed));
1026 }
1027
1028
1029 int scrw2glyph(unsigned short scr_word)
1030 {
1031 return ( video_mode_512ch )
1032 ? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
1033 : scr_word & 0x00ff;
1034 }
1035
1036
1037 unsigned short *screen_pos(int currcons, int w_offset, int viewed)
1038 {
1039 return screenpos(currcons, 2 * w_offset, viewed);
1040 }
1041
1042 void getconsxy(int currcons, char *p)
1043 {
1044 p[0] = x;
1045 p[1] = y;
1046 }
1047
1048 void putconsxy(int currcons, char *p)
1049 {
1050 gotoxy(currcons, p[0], p[1]);
1051 set_cursor(currcons);
1052 }
1053
1054 static void set_mode(int currcons, int on_off)
1055 {
1056 int i;
1057
1058 for (i=0; i<=npar; i++)
1059 if (ques) switch(par[i]) {
1060 case 1:
1061 if (on_off)
1062 set_kbd(decckm);
1063 else
1064 clr_kbd(decckm);
1065 break;
1066 case 3:
1067 deccolm = on_off;
1068 #if 0
1069 (void) vc_resize(video_num_lines, deccolm ? 132 : 80);
1070
1071
1072 #endif
1073 break;
1074 case 5:
1075 if (decscnm != on_off) {
1076 decscnm = on_off;
1077 invert_screen(currcons, 0, video_screen_size, 0);
1078 update_attr(currcons);
1079 }
1080 break;
1081 case 6:
1082 decom = on_off;
1083 gotoxy(currcons,0,0);
1084 break;
1085 case 7:
1086 decawm = on_off;
1087 break;
1088 case 8:
1089 if (on_off)
1090 set_kbd(decarm);
1091 else
1092 clr_kbd(decarm);
1093 break;
1094 case 9:
1095 report_mouse = on_off ? 1 : 0;
1096 break;
1097 case 25:
1098 deccm = on_off;
1099 set_cursor(currcons);
1100 break;
1101 case 1000:
1102 report_mouse = on_off ? 2 : 0;
1103 break;
1104 } else switch(par[i]) {
1105 case 3:
1106 disp_ctrl = on_off;
1107 break;
1108 case 4:
1109 decim = on_off;
1110 break;
1111 case 20:
1112 if (on_off)
1113 set_kbd(lnm);
1114 else
1115 clr_kbd(lnm);
1116 break;
1117 }
1118 }
1119
1120 static void setterm_command(int currcons)
1121 {
1122 switch(par[0]) {
1123 case 1:
1124 if (can_do_color && par[1] < 16) {
1125 ulcolor = color_table[par[1]];
1126 if (underline)
1127 update_attr(currcons);
1128 }
1129 break;
1130 case 2:
1131 if (can_do_color && par[1] < 16) {
1132 halfcolor = color_table[par[1]];
1133 if (intensity == 0)
1134 update_attr(currcons);
1135 }
1136 break;
1137 case 8:
1138 def_color = attr;
1139 default_attr(currcons);
1140 update_attr(currcons);
1141 break;
1142 case 9:
1143 blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
1144 poke_blanked_console();
1145 break;
1146 case 10:
1147 if (npar >= 1)
1148 bell_pitch = par[1];
1149 else
1150 bell_pitch = DEFAULT_BELL_PITCH;
1151 break;
1152 case 11:
1153 if (npar >= 1)
1154 bell_duration = (par[1] < 2000) ?
1155 par[1]*HZ/1000 : 0;
1156 else
1157 bell_duration = DEFAULT_BELL_DURATION;
1158 break;
1159 case 12:
1160 if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
1161 update_screen(par[1]-1);
1162 break;
1163 case 13:
1164 unblank_screen();
1165 break;
1166 case 14:
1167 vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
1168 break;
1169 }
1170 }
1171
1172 static void insert_char(int currcons)
1173 {
1174 unsigned int i = x;
1175 unsigned short tmp, old = video_erase_char;
1176 unsigned short * p = (unsigned short *) pos;
1177
1178 while (i++ < video_num_columns) {
1179 tmp = scr_readw(p);
1180 scr_writew(old, p);
1181 old = tmp;
1182 p++;
1183 }
1184 need_wrap = 0;
1185 }
1186
1187 static void insert_line(int currcons)
1188 {
1189 scrdown(currcons,y,bottom);
1190 need_wrap = 0;
1191 }
1192
1193 static void delete_char(int currcons)
1194 {
1195 unsigned int i = x;
1196 unsigned short * p = (unsigned short *) pos;
1197
1198 while (++i < video_num_columns) {
1199 scr_writew(scr_readw(p+1), p);
1200 p++;
1201 }
1202 scr_writew(video_erase_char, p);
1203 need_wrap = 0;
1204 }
1205
1206 static void delete_line(int currcons)
1207 {
1208 scrup(currcons,y,bottom);
1209 need_wrap = 0;
1210 }
1211
1212 static void csi_at(int currcons, unsigned int nr)
1213 {
1214 if (nr > video_num_columns)
1215 nr = video_num_columns;
1216 else if (!nr)
1217 nr = 1;
1218 while (nr--)
1219 insert_char(currcons);
1220 }
1221
1222 static void csi_L(int currcons, unsigned int nr)
1223 {
1224 if (nr > video_num_lines)
1225 nr = video_num_lines;
1226 else if (!nr)
1227 nr = 1;
1228 while (nr--)
1229 insert_line(currcons);
1230 }
1231
1232 static void csi_P(int currcons, unsigned int nr)
1233 {
1234 if (nr > video_num_columns)
1235 nr = video_num_columns;
1236 else if (!nr)
1237 nr = 1;
1238 while (nr--)
1239 delete_char(currcons);
1240 }
1241
1242 static void csi_M(int currcons, unsigned int nr)
1243 {
1244 if (nr > video_num_lines)
1245 nr = video_num_lines;
1246 else if (!nr)
1247 nr=1;
1248 while (nr--)
1249 delete_line(currcons);
1250 }
1251
1252 static void save_cur(int currcons)
1253 {
1254 saved_x = x;
1255 saved_y = y;
1256 s_intensity = intensity;
1257 s_underline = underline;
1258 s_blink = blink;
1259 s_reverse = reverse;
1260 s_charset = charset;
1261 s_color = color;
1262 saved_G0 = G0_charset;
1263 saved_G1 = G1_charset;
1264 }
1265
1266 static void restore_cur(int currcons)
1267 {
1268 gotoxy(currcons,saved_x,saved_y);
1269 intensity = s_intensity;
1270 underline = s_underline;
1271 blink = s_blink;
1272 reverse = s_reverse;
1273 charset = s_charset;
1274 color = s_color;
1275 G0_charset = saved_G0;
1276 G1_charset = saved_G1;
1277 translate = set_translate(charset ? G1_charset : G0_charset);
1278 update_attr(currcons);
1279 need_wrap = 0;
1280 }
1281
1282 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
1283 EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
1284 ESpalette };
1285
1286 static void reset_terminal(int currcons, int do_clear)
1287 {
1288 top = 0;
1289 bottom = video_num_lines;
1290 vc_state = ESnormal;
1291 ques = 0;
1292 translate = set_translate(LAT1_MAP);
1293 G0_charset = LAT1_MAP;
1294 G1_charset = GRAF_MAP;
1295 charset = 0;
1296 need_wrap = 0;
1297 report_mouse = 0;
1298 utf = 0;
1299 utf_count = 0;
1300
1301 disp_ctrl = 0;
1302 toggle_meta = 0;
1303
1304 decscnm = 0;
1305 decom = 0;
1306 decawm = 1;
1307 deccm = 1;
1308 decim = 0;
1309
1310 set_kbd(decarm);
1311 clr_kbd(decckm);
1312 clr_kbd(kbdapplic);
1313 clr_kbd(lnm);
1314 kbd_table[currcons].lockstate = 0;
1315 kbd_table[currcons].slockstate = 0;
1316 kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
1317 kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
1318 set_leds();
1319
1320 default_attr(currcons);
1321 update_attr(currcons);
1322
1323 tab_stop[0] = 0x01010100;
1324 tab_stop[1] =
1325 tab_stop[2] =
1326 tab_stop[3] =
1327 tab_stop[4] = 0x01010101;
1328
1329 bell_pitch = DEFAULT_BELL_PITCH;
1330 bell_duration = DEFAULT_BELL_DURATION;
1331
1332 gotoxy(currcons,0,0);
1333 save_cur(currcons);
1334 if (do_clear)
1335 csi_J(currcons,2);
1336 }
1337
1338
1339
1340
1341 static void con_stop(struct tty_struct *tty)
1342 {
1343 int console_num;
1344 if (!tty)
1345 return;
1346 console_num = MINOR(tty->device) - (tty->driver.minor_start);
1347 if (!vc_cons_allocated(console_num))
1348 return;
1349 set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1350 set_leds();
1351 }
1352
1353
1354
1355
1356 static void con_start(struct tty_struct *tty)
1357 {
1358 int console_num;
1359 if (!tty)
1360 return;
1361 console_num = MINOR(tty->device) - (tty->driver.minor_start);
1362 if (!vc_cons_allocated(console_num))
1363 return;
1364 clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1365 set_leds();
1366 }
1367
1368 static int con_write(struct tty_struct * tty, int from_user,
1369 const unsigned char *buf, int count)
1370 {
1371 int c, tc, ok, n = 0;
1372 unsigned int currcons;
1373 struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
1374
1375 currcons = vt->vc_num;
1376 if (!vc_cons_allocated(currcons)) {
1377
1378 static int error = 0;
1379 if (!error) {
1380 error = 1;
1381 printk("con_write: tty %d not allocated\n", currcons+1);
1382 }
1383 return 0;
1384 }
1385
1386 if (currcons == sel_cons)
1387 clear_selection();
1388
1389 disable_bh(CONSOLE_BH);
1390 while (!tty->stopped && count) {
1391 c = from_user ? get_user(buf) : *buf;
1392 buf++; n++; count--;
1393
1394 if (utf) {
1395
1396
1397 if(c > 0x7f) {
1398 if (utf_count > 0 && (c & 0xc0) == 0x80) {
1399 utf_char = (utf_char << 6) | (c & 0x3f);
1400 utf_count--;
1401 if (utf_count == 0)
1402 tc = c = utf_char;
1403 else continue;
1404 } else {
1405 if ((c & 0xe0) == 0xc0) {
1406 utf_count = 1;
1407 utf_char = (c & 0x1f);
1408 } else if ((c & 0xf0) == 0xe0) {
1409 utf_count = 2;
1410 utf_char = (c & 0x0f);
1411 } else if ((c & 0xf8) == 0xf0) {
1412 utf_count = 3;
1413 utf_char = (c & 0x07);
1414 } else if ((c & 0xfc) == 0xf8) {
1415 utf_count = 4;
1416 utf_char = (c & 0x03);
1417 } else if ((c & 0xfe) == 0xfc) {
1418 utf_count = 5;
1419 utf_char = (c & 0x01);
1420 } else
1421 utf_count = 0;
1422 continue;
1423 }
1424 } else {
1425 tc = c;
1426 utf_count = 0;
1427 }
1428 } else {
1429 tc = translate[toggle_meta ? (c|0x80) : c];
1430 }
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441 ok = (tc && (c >= 32 || (!utf && !(((disp_ctrl ? CTRL_ALWAYS
1442 : CTRL_ACTION) >> c) & 1))));
1443
1444 if (vc_state == ESnormal && ok) {
1445
1446 tc = conv_uni_to_pc(tc);
1447 if ( tc == -4 )
1448 {
1449
1450
1451 tc = conv_uni_to_pc(0xfffd);
1452 }
1453 else if ( tc == -3 )
1454 {
1455
1456 tc = c;
1457 }
1458 if (tc & ~console_charmask)
1459 continue;
1460
1461 if (need_wrap) {
1462 cr(currcons);
1463 lf(currcons);
1464 }
1465 if (decim)
1466 insert_char(currcons);
1467 scr_writew( video_mode_512ch ?
1468 ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
1469 (tc & 0x0ff) : (attr << 8) + tc,
1470 (unsigned short *) pos);
1471 if (x == video_num_columns - 1)
1472 need_wrap = decawm;
1473 else {
1474 x++;
1475 pos+=2;
1476 }
1477 continue;
1478 }
1479
1480
1481
1482
1483
1484 switch (c) {
1485 case 7:
1486 if (bell_duration)
1487 kd_mksound(bell_pitch, bell_duration);
1488 continue;
1489 case 8:
1490 bs(currcons);
1491 continue;
1492 case 9:
1493 pos -= (x << 1);
1494 while (x < video_num_columns - 1) {
1495 x++;
1496 if (tab_stop[x >> 5] & (1 << (x & 31)))
1497 break;
1498 }
1499 pos += (x << 1);
1500 continue;
1501 case 10: case 11: case 12:
1502 lf(currcons);
1503 if (!is_kbd(lnm))
1504 continue;
1505 case 13:
1506 cr(currcons);
1507 continue;
1508 case 14:
1509 charset = 1;
1510 translate = set_translate(G1_charset);
1511 disp_ctrl = 1;
1512 continue;
1513 case 15:
1514 charset = 0;
1515 translate = set_translate(G0_charset);
1516 disp_ctrl = 0;
1517 continue;
1518 case 24: case 26:
1519 vc_state = ESnormal;
1520 continue;
1521 case 27:
1522 vc_state = ESesc;
1523 continue;
1524 case 127:
1525 del(currcons);
1526 continue;
1527 case 128+27:
1528 vc_state = ESsquare;
1529 continue;
1530 }
1531 switch(vc_state) {
1532 case ESesc:
1533 vc_state = ESnormal;
1534 switch (c) {
1535 case '[':
1536 vc_state = ESsquare;
1537 continue;
1538 case ']':
1539 vc_state = ESnonstd;
1540 continue;
1541 case '%':
1542 vc_state = ESpercent;
1543 continue;
1544 case 'E':
1545 cr(currcons);
1546 lf(currcons);
1547 continue;
1548 case 'M':
1549 ri(currcons);
1550 continue;
1551 case 'D':
1552 lf(currcons);
1553 continue;
1554 case 'H':
1555 tab_stop[x >> 5] |= (1 << (x & 31));
1556 continue;
1557 case 'Z':
1558 respond_ID(tty);
1559 continue;
1560 case '7':
1561 save_cur(currcons);
1562 continue;
1563 case '8':
1564 restore_cur(currcons);
1565 continue;
1566 case '(':
1567 vc_state = ESsetG0;
1568 continue;
1569 case ')':
1570 vc_state = ESsetG1;
1571 continue;
1572 case '#':
1573 vc_state = EShash;
1574 continue;
1575 case 'c':
1576 reset_terminal(currcons,1);
1577 continue;
1578 case '>':
1579 clr_kbd(kbdapplic);
1580 continue;
1581 case '=':
1582 set_kbd(kbdapplic);
1583 continue;
1584 }
1585 continue;
1586 case ESnonstd:
1587 if (c=='P') {
1588 for (npar=0; npar<NPAR; npar++)
1589 par[npar] = 0 ;
1590 npar = 0 ;
1591 vc_state = ESpalette;
1592 continue;
1593 } else if (c=='R') {
1594 reset_palette (currcons);
1595 vc_state = ESnormal;
1596 } else
1597 vc_state = ESnormal;
1598 continue;
1599 case ESpalette:
1600 if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
1601 par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
1602 if (npar==7) {
1603 int i = par[0]*3, j = 1;
1604 palette[i] = 16*par[j++];
1605 palette[i++] += par[j++];
1606 palette[i] = 16*par[j++];
1607 palette[i++] += par[j++];
1608 palette[i] = 16*par[j++];
1609 palette[i] += par[j];
1610 set_palette() ;
1611 vc_state = ESnormal;
1612 }
1613 } else
1614 vc_state = ESnormal;
1615 continue;
1616 case ESsquare:
1617 for(npar = 0 ; npar < NPAR ; npar++)
1618 par[npar] = 0;
1619 npar = 0;
1620 vc_state = ESgetpars;
1621 if (c == '[') {
1622 vc_state=ESfunckey;
1623 continue;
1624 }
1625 ques = (c=='?');
1626 if (ques)
1627 continue;
1628 case ESgetpars:
1629 if (c==';' && npar<NPAR-1) {
1630 npar++;
1631 continue;
1632 } else if (c>='0' && c<='9') {
1633 par[npar] *= 10;
1634 par[npar] += c-'0';
1635 continue;
1636 } else vc_state=ESgotpars;
1637 case ESgotpars:
1638 vc_state = ESnormal;
1639 switch(c) {
1640 case 'h':
1641 set_mode(currcons,1);
1642 continue;
1643 case 'l':
1644 set_mode(currcons,0);
1645 continue;
1646 case 'n':
1647 if (!ques)
1648 if (par[0] == 5)
1649 status_report(tty);
1650 else if (par[0] == 6)
1651 cursor_report(currcons,tty);
1652 continue;
1653 }
1654 if (ques) {
1655 ques = 0;
1656 continue;
1657 }
1658 switch(c) {
1659 case 'G': case '`':
1660 if (par[0]) par[0]--;
1661 gotoxy(currcons,par[0],y);
1662 continue;
1663 case 'A':
1664 if (!par[0]) par[0]++;
1665 gotoxy(currcons,x,y-par[0]);
1666 continue;
1667 case 'B': case 'e':
1668 if (!par[0]) par[0]++;
1669 gotoxy(currcons,x,y+par[0]);
1670 continue;
1671 case 'C': case 'a':
1672 if (!par[0]) par[0]++;
1673 gotoxy(currcons,x+par[0],y);
1674 continue;
1675 case 'D':
1676 if (!par[0]) par[0]++;
1677 gotoxy(currcons,x-par[0],y);
1678 continue;
1679 case 'E':
1680 if (!par[0]) par[0]++;
1681 gotoxy(currcons,0,y+par[0]);
1682 continue;
1683 case 'F':
1684 if (!par[0]) par[0]++;
1685 gotoxy(currcons,0,y-par[0]);
1686 continue;
1687 case 'd':
1688 if (par[0]) par[0]--;
1689 gotoxy(currcons,x,par[0]);
1690 continue;
1691 case 'H': case 'f':
1692 if (par[0]) par[0]--;
1693 if (par[1]) par[1]--;
1694 gotoxy(currcons,par[1],par[0]);
1695 continue;
1696 case 'J':
1697 csi_J(currcons,par[0]);
1698 continue;
1699 case 'K':
1700 csi_K(currcons,par[0]);
1701 continue;
1702 case 'L':
1703 csi_L(currcons,par[0]);
1704 continue;
1705 case 'M':
1706 csi_M(currcons,par[0]);
1707 continue;
1708 case 'P':
1709 csi_P(currcons,par[0]);
1710 continue;
1711 case 'c':
1712 if (!par[0])
1713 respond_ID(tty);
1714 continue;
1715 case 'g':
1716 if (!par[0])
1717 tab_stop[x >> 5] &= ~(1 << (x & 31));
1718 else if (par[0] == 3) {
1719 tab_stop[0] =
1720 tab_stop[1] =
1721 tab_stop[2] =
1722 tab_stop[3] =
1723 tab_stop[4] = 0;
1724 }
1725 continue;
1726 case 'm':
1727 csi_m(currcons);
1728 continue;
1729 case 'q':
1730
1731 if (par[0] < 4)
1732 setledstate(kbd_table + currcons,
1733 (par[0] < 3) ? par[0] : 4);
1734 continue;
1735 case 'r':
1736 if (!par[0])
1737 par[0]++;
1738 if (!par[1])
1739 par[1] = video_num_lines;
1740
1741 if (par[0] < par[1] &&
1742 par[1] <= video_num_lines) {
1743 top=par[0]-1;
1744 bottom=par[1];
1745 gotoxy(currcons,0,0);
1746 }
1747 continue;
1748 case 's':
1749 save_cur(currcons);
1750 continue;
1751 case 'u':
1752 restore_cur(currcons);
1753 continue;
1754 case 'X':
1755 csi_X(currcons, par[0]);
1756 continue;
1757 case '@':
1758 csi_at(currcons,par[0]);
1759 continue;
1760 case ']':
1761 setterm_command(currcons);
1762 continue;
1763 }
1764 continue;
1765 case ESpercent:
1766 vc_state = ESnormal;
1767 switch (c) {
1768 case '@':
1769 utf = 0;
1770 continue;
1771 case 'G':
1772 case '8':
1773 utf = 1;
1774 continue;
1775 }
1776 continue;
1777 case ESfunckey:
1778 vc_state = ESnormal;
1779 continue;
1780 case EShash:
1781 vc_state = ESnormal;
1782 if (c == '8') {
1783
1784 video_erase_char =
1785 (video_erase_char & 0xff00) | 'E';
1786 csi_J(currcons, 2);
1787 video_erase_char =
1788 (video_erase_char & 0xff00) | ' ';
1789 }
1790 continue;
1791 case ESsetG0:
1792 if (c == '0')
1793 G0_charset = GRAF_MAP;
1794 else if (c == 'B')
1795 G0_charset = LAT1_MAP;
1796 else if (c == 'U')
1797 G0_charset = IBMPC_MAP;
1798 else if (c == 'K')
1799 G0_charset = USER_MAP;
1800 if (charset == 0)
1801 translate = set_translate(G0_charset);
1802 vc_state = ESnormal;
1803 continue;
1804 case ESsetG1:
1805 if (c == '0')
1806 G1_charset = GRAF_MAP;
1807 else if (c == 'B')
1808 G1_charset = LAT1_MAP;
1809 else if (c == 'U')
1810 G1_charset = IBMPC_MAP;
1811 else if (c == 'K')
1812 G1_charset = USER_MAP;
1813 if (charset == 1)
1814 translate = set_translate(G1_charset);
1815 vc_state = ESnormal;
1816 continue;
1817 default:
1818 vc_state = ESnormal;
1819 }
1820 }
1821 if (vcmode != KD_GRAPHICS)
1822 set_cursor(currcons);
1823 enable_bh(CONSOLE_BH);
1824 return n;
1825 }
1826
1827 static int con_write_room(struct tty_struct *tty)
1828 {
1829 if (tty->stopped)
1830 return 0;
1831 return 4096;
1832 }
1833
1834 static int con_chars_in_buffer(struct tty_struct *tty)
1835 {
1836 return 0;
1837 }
1838
1839 void poke_blanked_console(void)
1840 {
1841 timer_active &= ~(1<<BLANK_TIMER);
1842 if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
1843 return;
1844 if (console_blanked) {
1845 timer_table[BLANK_TIMER].fn = unblank_screen;
1846 timer_table[BLANK_TIMER].expires = 0;
1847 timer_active |= 1<<BLANK_TIMER;
1848 } else if (blankinterval) {
1849 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1850 timer_active |= 1<<BLANK_TIMER;
1851 }
1852 }
1853
1854 void console_print(const char * b)
1855 {
1856 int currcons = fg_console;
1857 unsigned char c;
1858 static int printing = 0;
1859
1860 if (!printable || printing)
1861 return;
1862 printing = 1;
1863
1864 if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
1865 currcons = kmsg_redirect - 1;
1866
1867 if (!vc_cons_allocated(currcons)) {
1868
1869 printk("console_print: tty %d not allocated ??\n", currcons+1);
1870 return;
1871 }
1872
1873 #ifdef CONFIG_SERIAL_ECHO
1874 serial_echo_print(b);
1875 #endif
1876
1877 while ((c = *(b++)) != 0) {
1878 if (c == 10 || c == 13 || need_wrap) {
1879 if (c != 13)
1880 lf(currcons);
1881 cr(currcons);
1882 if (c == 10 || c == 13)
1883 continue;
1884 }
1885 if (c == 8) {
1886 bs(currcons);
1887 continue;
1888 }
1889 scr_writew((attr << 8) + c, (unsigned short *) pos);
1890 if (x == video_num_columns - 1) {
1891 need_wrap = 1;
1892 continue;
1893 }
1894 x++;
1895 pos+=2;
1896 }
1897 set_cursor(currcons);
1898 poke_blanked_console();
1899 printing = 0;
1900 }
1901
1902
1903
1904
1905
1906
1907 static void con_throttle(struct tty_struct *tty)
1908 {
1909 }
1910
1911 static void con_unthrottle(struct tty_struct *tty)
1912 {
1913 struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
1914
1915 wake_up_interruptible(&vt->paste_wait);
1916 }
1917
1918 static void vc_init(unsigned int currcons, unsigned long rows, unsigned long cols, int do_clear)
1919 {
1920 long base = (long) vc_scrbuf[currcons];
1921 int j, k ;
1922
1923 video_num_columns = cols;
1924 video_num_lines = rows;
1925 video_size_row = cols<<1;
1926 video_screen_size = video_num_lines * video_size_row;
1927
1928 pos = origin = video_mem_start = base;
1929 scr_end = base + video_screen_size;
1930 video_mem_end = base + video_screen_size;
1931 reset_vc(currcons);
1932 for (j=k=0; j<16; j++) {
1933 vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
1934 vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
1935 vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
1936 }
1937 def_color = 0x07;
1938 ulcolor = 0x0f;
1939 halfcolor = 0x08;
1940 vt_cons[currcons]->paste_wait = 0;
1941 reset_terminal(currcons, do_clear);
1942 }
1943
1944 static void con_setsize(unsigned long rows, unsigned long cols)
1945 {
1946 video_num_lines = rows;
1947 video_num_columns = cols;
1948 video_size_row = 2 * cols;
1949 video_screen_size = video_num_lines * video_size_row;
1950 }
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961 static void console_bh(void)
1962 {
1963 if (want_console >= 0) {
1964 if (want_console != fg_console) {
1965 change_console(want_console);
1966
1967
1968
1969 }
1970 want_console = -1;
1971 }
1972 if (do_poke_blanked_console) {
1973 do_poke_blanked_console = 0;
1974 poke_blanked_console();
1975 }
1976 }
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988 unsigned long con_init(unsigned long kmem_start)
1989 {
1990 const char *display_desc = "????";
1991 int currcons = 0;
1992 int orig_x = ORIG_X;
1993 int orig_y = ORIG_Y;
1994
1995 memset(&console_driver, 0, sizeof(struct tty_driver));
1996 console_driver.magic = TTY_DRIVER_MAGIC;
1997 console_driver.name = "tty";
1998 console_driver.name_base = 1;
1999 console_driver.major = TTY_MAJOR;
2000 console_driver.minor_start = 1;
2001 console_driver.num = MAX_NR_CONSOLES;
2002 console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
2003 console_driver.init_termios = tty_std_termios;
2004 console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
2005 console_driver.refcount = &console_refcount;
2006 console_driver.table = console_table;
2007 console_driver.termios = console_termios;
2008 console_driver.termios_locked = console_termios_locked;
2009
2010 console_driver.open = con_open;
2011 console_driver.write = con_write;
2012 console_driver.write_room = con_write_room;
2013 console_driver.chars_in_buffer = con_chars_in_buffer;
2014 console_driver.ioctl = vt_ioctl;
2015 console_driver.stop = con_stop;
2016 console_driver.start = con_start;
2017 console_driver.throttle = con_throttle;
2018 console_driver.unthrottle = con_unthrottle;
2019
2020 if (tty_register_driver(&console_driver))
2021 panic("Couldn't register console driver\n");
2022
2023 con_setsize(ORIG_VIDEO_LINES, ORIG_VIDEO_COLS);
2024 video_page = ORIG_VIDEO_PAGE;
2025 __scrollback_mode = 0 ;
2026
2027 timer_table[BLANK_TIMER].fn = blank_screen;
2028 timer_table[BLANK_TIMER].expires = 0;
2029 if (blankinterval) {
2030 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2031 timer_active |= 1<<BLANK_TIMER;
2032 }
2033
2034 kmem_start = con_type_init(kmem_start, &display_desc);
2035
2036
2037
2038
2039
2040 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
2041 int j, k ;
2042
2043 vc_cons[currcons].d = (struct vc_data *) kmem_start;
2044 kmem_start += sizeof(struct vc_data);
2045 vt_cons[currcons] = (struct vt_struct *) kmem_start;
2046 kmem_start += sizeof(struct vt_struct);
2047 vc_scrbuf[currcons] = (unsigned short *) kmem_start;
2048 kmem_start += video_screen_size;
2049 kmalloced = 0;
2050 screenbuf_size = video_screen_size;
2051 vc_init(currcons, video_num_lines, video_num_columns, currcons);
2052 for (j=k=0; j<16; j++) {
2053 vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
2054 vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
2055 vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
2056 }
2057 }
2058
2059 currcons = fg_console = 0;
2060
2061 video_mem_start = video_mem_base;
2062 video_mem_end = video_mem_term;
2063 origin = video_mem_start;
2064 scr_end = video_mem_start + video_num_lines * video_size_row;
2065 gotoxy(currcons,orig_x,orig_y);
2066 set_origin(currcons);
2067 csi_J(currcons, 0);
2068
2069
2070
2071
2072
2073 printable = 1;
2074 if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC
2075 || video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC )
2076 {
2077 default_font_height = video_font_height = ORIG_VIDEO_POINTS;
2078
2079 video_scan_lines = video_font_height * video_num_lines;
2080
2081 #ifdef CONFIG_SERIAL_ECHO
2082 serial_echo_init(SERIAL_ECHO_PORT);
2083 #endif
2084
2085 printk("Console: %ld point font, %ld scans\n",
2086 video_font_height, video_scan_lines);
2087 }
2088
2089 printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
2090 can_do_color ? "colour" : "mono",
2091 display_desc, video_num_columns, video_num_lines,
2092 MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s",
2093 MAX_NR_CONSOLES);
2094
2095
2096
2097
2098
2099
2100
2101 if (video_type != VIDEO_TYPE_TGAC)
2102 register_console(console_print);
2103
2104 init_bh(CONSOLE_BH, console_bh);
2105 return kmem_start;
2106 }
2107
2108 void vesa_powerdown_screen(void)
2109 {
2110 timer_active &= ~(1<<BLANK_TIMER);
2111 timer_table[BLANK_TIMER].fn = unblank_screen;
2112
2113 vesa_powerdown();
2114 }
2115
2116 void do_blank_screen(int nopowersave)
2117 {
2118 int currcons;
2119
2120 #ifdef CONFIG_APM
2121 if (apm_display_blank())
2122 return;
2123 #endif
2124
2125 if (console_blanked)
2126 return;
2127
2128 if(vesa_off_interval && !nopowersave) {
2129 timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
2130 timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
2131 timer_active |= (1<<BLANK_TIMER);
2132 } else {
2133 timer_active &= ~(1<<BLANK_TIMER);
2134 timer_table[BLANK_TIMER].fn = unblank_screen;
2135 }
2136
2137
2138 currcons = fg_console;
2139 has_scrolled = 0;
2140 blank__origin = __origin;
2141 blank_origin = origin;
2142 set_origin(fg_console);
2143 get_scrmem(fg_console);
2144 unblank_origin = origin;
2145 memsetw((void *)blank_origin, BLANK,
2146 2*video_num_lines*video_num_columns);
2147 hide_cursor();
2148 console_blanked = fg_console + 1;
2149
2150 if(!nopowersave)
2151 vesa_blank();
2152 }
2153
2154 void do_unblank_screen(void)
2155 {
2156 int currcons;
2157 int resetorg;
2158 long offset;
2159
2160 #ifdef CONFIG_APM
2161 if (apm_display_unblank())
2162 return;
2163 #endif
2164
2165 if (!console_blanked)
2166 return;
2167 if (!vc_cons_allocated(fg_console)) {
2168
2169 printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
2170 return;
2171 }
2172 timer_table[BLANK_TIMER].fn = blank_screen;
2173 if (blankinterval) {
2174 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2175 timer_active |= 1<<BLANK_TIMER;
2176 }
2177
2178 currcons = fg_console;
2179 offset = 0;
2180 resetorg = 0;
2181 if (console_blanked == fg_console + 1 && origin == unblank_origin
2182 && !has_scrolled) {
2183
2184 resetorg = 1;
2185 offset = (blank_origin - video_mem_base)
2186 - (unblank_origin - video_mem_start);
2187 }
2188
2189 console_blanked = 0;
2190 set_scrmem(fg_console, offset);
2191 set_origin(fg_console);
2192 set_cursor(fg_console);
2193 if (resetorg)
2194 __set_origin(blank__origin);
2195
2196 vesa_unblank();
2197 }
2198
2199
2200
2201
2202
2203 static void blank_screen(void)
2204 {
2205 do_blank_screen(0);
2206 }
2207
2208 static void unblank_screen(void)
2209 {
2210 do_unblank_screen();
2211 }
2212
2213 void update_screen(int new_console)
2214 {
2215 static int lock = 0;
2216
2217 if (new_console == fg_console || lock)
2218 return;
2219 if (!vc_cons_allocated(new_console)) {
2220
2221 printk("update_screen: tty %d not allocated ??\n", new_console+1);
2222 return;
2223 }
2224 lock = 1;
2225
2226 clear_selection();
2227
2228 if (!console_blanked)
2229 get_scrmem(fg_console);
2230 else
2231 console_blanked = -1;
2232 fg_console = new_console;
2233
2234 set_scrmem(fg_console, 0);
2235 set_origin(fg_console);
2236 set_cursor(fg_console);
2237 set_leds();
2238 compute_shiftstate();
2239 lock = 0;
2240 }
2241
2242
2243
2244
2245 int con_open(struct tty_struct *tty, struct file * filp)
2246 {
2247 unsigned int idx;
2248 int i;
2249
2250 idx = MINOR(tty->device) - tty->driver.minor_start;
2251
2252 i = vc_allocate(idx);
2253 if (i)
2254 return i;
2255
2256 vt_cons[idx]->vc_num = idx;
2257 tty->driver_data = vt_cons[idx];
2258
2259 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2260 tty->winsize.ws_row = video_num_lines;
2261 tty->winsize.ws_col = video_num_columns;
2262 }
2263 return 0;
2264 }
2265
2266
2267
2268
2269
2270
2271
2272 int con_set_cmap (unsigned char *arg)
2273 {
2274 return set_get_cmap (arg,1);
2275 }
2276
2277 int con_get_cmap (unsigned char *arg)
2278 {
2279 return set_get_cmap (arg,0);
2280 }
2281
2282 void reset_palette (int currcons)
2283 {
2284 int j, k ;
2285 for (j=k=0; j<16; j++) {
2286 palette[k++] = default_red[j];
2287 palette[k++] = default_grn[j];
2288 palette[k++] = default_blu[j];
2289 }
2290 set_palette() ;
2291 }
2292
2293
2294
2295
2296
2297
2298
2299 int con_set_font (char *arg, int ch512)
2300 {
2301 int i;
2302
2303 i = set_get_font (arg,1,ch512);
2304 if ( !i ) {
2305 hashtable_contents_valid = 0;
2306 video_mode_512ch = ch512;
2307 console_charmask = ch512 ? 0x1ff : 0x0ff;
2308 }
2309 return i;
2310 }
2311
2312 int con_get_font (char *arg)
2313 {
2314 return set_get_font (arg,0,video_mode_512ch);
2315 }