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