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