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