This source file includes following definitions.
- serial_echo_print
- serial_echo_init
- vc_cons_allocated
- vc_allocate
- vc_resize
- vc_disallocate
- gotoxy
- no_scroll
- scrolldelta
- scrollback
- scrollfront
- set_origin
- scrup
- scrdown
- lf
- ri
- cr
- bs
- del
- csi_J
- csi_K
- csi_X
- update_attr
- default_attr
- csi_m
- respond_string
- cursor_report
- status_report
- respond_ID
- mouse_report
- mouse_reporting
- screenpos
- invert_screen
- complement_pos
- screen_word
- scrw2glyph
- screen_pos
- getconsxy
- putconsxy
- set_mode
- setterm_command
- insert_char
- insert_line
- delete_char
- delete_line
- csi_at
- csi_L
- csi_P
- csi_M
- save_cur
- restore_cur
- reset_terminal
- con_stop
- con_start
- con_write
- con_write_room
- con_chars_in_buffer
- poke_blanked_console
- console_print
- con_throttle
- con_unthrottle
- vc_init
- con_setsize
- console_bh
- con_init
- vesa_powerdown_screen
- do_blank_screen
- do_unblank_screen
- blank_screen
- unblank_screen
- update_screen
- con_open
- con_set_cmap
- con_get_cmap
- reset_palette
- con_set_font
- con_get_font
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 #define BLANK 0x0020
66
67
68
69
70
71
72 #define CTRL_ACTION 0x0d00ff81
73 #define CTRL_ALWAYS 0x0800f501
74
75
76
77
78 #define DEFAULT_BELL_PITCH 750
79 #define DEFAULT_BELL_DURATION (HZ/8)
80
81
82
83
84
85
86
87
88 #include <linux/sched.h>
89 #include <linux/timer.h>
90 #include <linux/interrupt.h>
91 #include <linux/tty.h>
92 #include <linux/tty_flip.h>
93 #include <linux/config.h>
94 #include <linux/kernel.h>
95 #include <linux/string.h>
96 #include <linux/errno.h>
97 #include <linux/kd.h>
98 #include <linux/malloc.h>
99 #include <linux/major.h>
100 #include <linux/mm.h>
101 #include <linux/ioport.h>
102 #ifdef CONFIG_APM
103 #include <linux/apm_bios.h>
104 #endif
105
106 #include <asm/io.h>
107 #include <asm/system.h>
108 #include <asm/segment.h>
109 #include <asm/bitops.h>
110
111 #include "kbd_kern.h"
112 #include "vt_kern.h"
113 #include "consolemap.h"
114 #include "selection.h"
115 #include "console_struct.h"
116
117 #ifndef MIN
118 #define MIN(a,b) ((a) < (b) ? (a) : (b))
119 #endif
120
121 struct tty_driver console_driver;
122 static int console_refcount;
123 static struct tty_struct *console_table[MAX_NR_CONSOLES];
124 static struct termios *console_termios[MAX_NR_CONSOLES];
125 static struct termios *console_termios_locked[MAX_NR_CONSOLES];
126 unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
127 struct vc vc_cons [MAX_NR_CONSOLES];
128
129 static void con_setsize(unsigned long rows, unsigned long cols);
130 static void vc_init(unsigned int console, unsigned long rows,
131 unsigned long cols, int do_clear);
132 extern void get_scrmem(int currcons);
133 extern void set_scrmem(int currcons, long offset);
134 static void set_origin(int currcons);
135 static void blank_screen(void);
136 static void unblank_screen(void);
137 extern void change_console(unsigned int);
138 extern void poke_blanked_console(void);
139 static void gotoxy(int currcons, int new_x, int new_y);
140 static void save_cur(int currcons);
141 extern void set_cursor(int currcons);
142 extern void hide_cursor(void);
143 static void reset_terminal(int currcons, int do_clear);
144 extern void reset_vc(unsigned int new_console);
145 extern void vt_init(void);
146 extern void register_console(void (*proc)(const char *));
147 extern void vesa_blank(void);
148 extern void vesa_unblank(void);
149 extern void vesa_powerdown(void);
150 extern void compute_shiftstate(void);
151 extern void reset_palette(int currcons);
152 extern void set_palette(void);
153 extern unsigned long con_type_init(unsigned long, const char **);
154 extern int set_get_cmap(unsigned char *, int);
155 extern int set_get_font(unsigned char *, int, int);
156
157
158 unsigned char video_type;
159 unsigned long video_mem_base;
160 unsigned long video_mem_term;
161 unsigned short video_port_reg;
162 unsigned short video_port_val;
163 unsigned long video_num_columns;
164 unsigned long video_num_lines;
165 unsigned long video_size_row;
166 unsigned long video_screen_size;
167
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
179 int do_poke_blanked_console = 0;
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
186 #ifdef CONFIG_SERIAL_ECHO
187
188 #include <linux/serial_reg.h>
189
190 extern int serial_echo_init (int base);
191 extern int serial_echo_print (const char *s);
192
193
194
195
196
197 #define SERIAL_ECHO_PORT 0x3f8
198
199 static int serial_echo_port = 0;
200
201 #define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port)
202 #define serial_echo_inb(a) inb((a)+serial_echo_port)
203
204 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
205
206
207 #define WAIT_FOR_XMITR \
208 do { \
209 lsr = serial_echo_inb(UART_LSR); \
210 } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY)
211
212
213
214
215
216 int
217 serial_echo_print(const char *s)
218 {
219 int lsr, ier;
220 int i;
221
222 if (!serial_echo_port) return (0);
223
224
225
226
227 ier = serial_echo_inb(UART_IER);
228 serial_echo_outb(0x00, UART_IER);
229
230
231
232
233 for (i = 0; *s; i++, s++) {
234 WAIT_FOR_XMITR;
235
236
237 serial_echo_outb(*s, UART_TX);
238
239
240 if (*s == 10) {
241 WAIT_FOR_XMITR;
242 serial_echo_outb(13, UART_TX);
243 }
244 }
245
246
247
248
249
250 do {
251 lsr = serial_echo_inb(UART_LSR);
252 } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
253 serial_echo_outb(ier, UART_IER);
254
255 return (0);
256 }
257
258
259 int
260 serial_echo_init(int base)
261 {
262 int comstat, hi, lo;
263
264 if (base != 0x2f8 && base != 0x3f8) {
265 serial_echo_port = 0;
266 return (0);
267 } else
268 serial_echo_port = base;
269
270
271
272
273 comstat = serial_echo_inb(UART_LCR);
274 serial_echo_outb(comstat | UART_LCR_DLAB, UART_LCR);
275 hi = serial_echo_inb(UART_DLM);
276 lo = serial_echo_inb(UART_DLL);
277 serial_echo_outb(comstat, UART_LCR);
278
279
280
281
282 serial_echo_outb(0x03, UART_LCR);
283 serial_echo_outb(0x83, UART_LCR);
284 serial_echo_outb(0x00, UART_DLM);
285 serial_echo_outb(0x0c, UART_DLL);
286 serial_echo_outb(0x03, UART_LCR);
287
288
289
290
291 comstat = serial_echo_inb(UART_LSR);
292 comstat = serial_echo_inb(UART_RX);
293 serial_echo_outb(0x00, UART_IER);
294
295 return(0);
296 }
297
298 #endif
299
300
301 int vc_cons_allocated(unsigned int i)
302 {
303 return (i < MAX_NR_CONSOLES && vc_cons[i].d);
304 }
305
306 int vc_allocate(unsigned int i)
307 {
308 if (i >= MAX_NR_CONSOLES)
309 return -ENODEV;
310 if (!vc_cons[i].d) {
311 long p, q;
312
313
314 if (i >= MAX_NR_USER_CONSOLES && !suser())
315 return -EPERM;
316
317
318
319
320 q = (long) kmalloc(video_screen_size, GFP_KERNEL);
321 if (!q)
322 return -ENOMEM;
323 p = (long) kmalloc(structsize, GFP_KERNEL);
324 if (!p) {
325 kfree_s((char *) q, video_screen_size);
326 return -ENOMEM;
327 }
328
329 vc_cons[i].d = (struct vc_data *) p;
330 p += sizeof(struct vc_data);
331 vt_cons[i] = (struct vt_struct *) p;
332 vc_scrbuf[i] = (unsigned short *) q;
333 vc_cons[i].d->vc_kmalloced = 1;
334 vc_cons[i].d->vc_screenbuf_size = video_screen_size;
335 vc_init (i, video_num_lines, video_num_columns, 1);
336 }
337 return 0;
338 }
339
340
341
342
343
344
345 int vc_resize(unsigned long lines, unsigned long cols)
346 {
347 unsigned long cc, ll, ss, sr;
348 unsigned long occ, oll, oss, osr;
349 unsigned short *p;
350 unsigned int currcons, i;
351 unsigned short *newscreens[MAX_NR_CONSOLES];
352 long ol, nl, rlth, rrem;
353
354 cc = (cols ? cols : video_num_columns);
355 ll = (lines ? lines : video_num_lines);
356 sr = cc << 1;
357 ss = sr * ll;
358
359 if (ss > video_mem_term - video_mem_base)
360 return -ENOMEM;
361
362
363
364
365
366
367
368 for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
369 if (!vc_cons_allocated(currcons))
370 newscreens[currcons] = 0;
371 else {
372 p = (unsigned short *) kmalloc(ss, GFP_USER);
373 if (!p) {
374 for (i = 0; i< currcons; i++)
375 if (newscreens[i])
376 kfree_s(newscreens[i], ss);
377 return -ENOMEM;
378 }
379 newscreens[currcons] = p;
380 }
381 }
382
383 get_scrmem(fg_console);
384
385 oll = video_num_lines;
386 occ = video_num_columns;
387 osr = video_size_row;
388 oss = video_screen_size;
389
390 video_num_lines = ll;
391 video_num_columns = cc;
392 video_size_row = sr;
393 video_screen_size = ss;
394
395 for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
396 if (!vc_cons_allocated(currcons))
397 continue;
398
399 rlth = MIN(osr, sr);
400 rrem = sr - rlth;
401 ol = origin;
402 nl = (long) newscreens[currcons];
403 if (ll < oll)
404 ol += (oll - ll) * osr;
405
406 while (ol < scr_end) {
407 memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
408 if (rrem)
409 memsetw((void *)(nl + rlth), video_erase_char, rrem);
410 ol += osr;
411 nl += sr;
412 }
413
414 if (kmalloced)
415 kfree_s(vc_scrbuf[currcons], screenbuf_size);
416 vc_scrbuf[currcons] = newscreens[currcons];
417 kmalloced = 1;
418 screenbuf_size = ss;
419
420 origin = video_mem_start = (long) vc_scrbuf[currcons];
421 scr_end = video_mem_end = video_mem_start + ss;
422
423 if (scr_end > nl)
424 memsetw((void *) nl, video_erase_char, scr_end - nl);
425
426
427 top = 0;
428 bottom = video_num_lines;
429 gotoxy(currcons, x, y);
430 save_cur(currcons);
431 }
432
433 set_scrmem(fg_console, 0);
434 set_origin(fg_console);
435 set_cursor(fg_console);
436
437 return 0;
438 }
439
440 void vc_disallocate(unsigned int currcons)
441 {
442 if (vc_cons_allocated(currcons)) {
443 if (kmalloced)
444 kfree_s(vc_scrbuf[currcons], screenbuf_size);
445 if (currcons >= MIN_NR_CONSOLES)
446 kfree_s(vc_cons[currcons].d, structsize);
447 vc_cons[currcons].d = 0;
448 }
449 }
450
451
452 #define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
453 #define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
454 #define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
455
456 #define decarm VC_REPEAT
457 #define decckm VC_CKMODE
458 #define kbdapplic VC_APPLIC
459 #define lnm VC_CRLF
460
461
462
463
464 #define VT100ID "\033[?1;2c"
465 #define VT102ID "\033[?6c"
466
467 unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
468 8,12,10,14, 9,13,11,15 };
469
470
471 int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
472 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
473 int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
474 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
475 int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
476 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
477
478
479
480
481
482
483 static void gotoxy(int currcons, int new_x, int new_y)
484 {
485 int max_y;
486
487 if (new_x < 0)
488 x = 0;
489 else
490 if (new_x >= video_num_columns)
491 x = video_num_columns - 1;
492 else
493 x = new_x;
494 if (decom) {
495 new_y += top;
496 max_y = bottom;
497 } else
498 max_y = video_num_lines;
499 if (new_y < 0)
500 y = 0;
501 else
502 if (new_y >= max_y)
503 y = max_y - 1;
504 else
505 y = new_y;
506 pos = origin + y*video_size_row + (x<<1);
507 need_wrap = 0;
508 }
509
510
511
512
513 extern void __set_origin(unsigned short);
514 unsigned short __real_origin;
515 unsigned short __origin;
516 unsigned char has_wrapped;
517 static unsigned char hardscroll_enabled;
518 static unsigned char hardscroll_disabled_by_init = 0;
519
520 void no_scroll(char *str, int *ints)
521 {
522
523
524
525
526
527 hardscroll_disabled_by_init = 1;
528 hardscroll_enabled = 0;
529 }
530
531 static void scrolldelta(int lines)
532 {
533 int new_origin;
534 int last_origin_rel = (((video_mem_term - video_mem_base)
535 / video_num_columns / 2) - (video_num_lines - 1)) * video_num_columns;
536
537 new_origin = __origin + lines * video_num_columns;
538 if (__origin > __real_origin)
539 new_origin -= last_origin_rel;
540 if (new_origin < 0) {
541 int s_top = __real_origin + video_num_lines*video_num_columns;
542 new_origin += last_origin_rel;
543 if (new_origin < s_top)
544 new_origin = s_top;
545 if (new_origin > last_origin_rel - video_num_columns
546 || has_wrapped == 0)
547 new_origin = 0;
548 else {
549 unsigned short * d = (unsigned short *) video_mem_base;
550 unsigned short * s = d + last_origin_rel;
551 int count = (video_num_lines-1)*video_num_columns;
552 while (count) {
553 count--;
554 scr_writew(scr_readw(d++),s++);
555 }
556 }
557 } else if (new_origin > __real_origin)
558 new_origin = __real_origin;
559
560 __set_origin(new_origin);
561 }
562
563 void scrollback(int lines)
564 {
565 if (!lines)
566 lines = video_num_lines/2;
567 scrolldelta(-lines);
568 }
569
570 void scrollfront(int lines)
571 {
572 if (!lines)
573 lines = video_num_lines/2;
574 scrolldelta(lines);
575 }
576
577 static void set_origin(int currcons)
578 {
579 if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_VGAC
580 && video_type != VIDEO_TYPE_EGAM)
581 return;
582 if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
583 return;
584 __real_origin = (origin-video_mem_base) >> 1;
585 __set_origin(__real_origin);
586 }
587
588 void scrup(int currcons, unsigned int t, unsigned int b)
589 {
590 int hardscroll = hardscroll_enabled;
591
592 if (b > video_num_lines || t >= b)
593 return;
594 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 (scr_end > video_mem_end) {
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 has_wrapped = 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 }
632 set_origin(currcons);
633 } else {
634 unsigned short * d = (unsigned short *) (origin+video_size_row*t);
635 unsigned short * s = (unsigned short *) (origin+video_size_row*(t+1));
636 unsigned int count = (b-t-1) * video_num_columns;
637
638 while (count) {
639 count--;
640 scr_writew(scr_readw(s++), d++);
641 }
642 count = video_num_columns;
643 while (count) {
644 count--;
645 scr_writew(video_erase_char, d++);
646 }
647 }
648 }
649
650 void
651 scrdown(int currcons, unsigned int t, unsigned int b)
652 {
653 unsigned short *d, *s;
654 unsigned int count;
655
656 if (b > video_num_lines || t >= b)
657 return;
658 d = (unsigned short *) (origin+video_size_row*b);
659 s = (unsigned short *) (origin+video_size_row*(b-1));
660 count = (b-t-1)*video_num_columns;
661 while (count) {
662 count--;
663 scr_writew(scr_readw(--s), --d);
664 }
665 count = video_num_columns;
666 while (count) {
667 count--;
668 scr_writew(video_erase_char, --d);
669 }
670 has_scrolled = 1;
671 }
672
673 static void lf(int currcons)
674 {
675
676
677
678 if (y+1 == bottom)
679 scrup(currcons,top,bottom);
680 else if (y < video_num_lines-1) {
681 y++;
682 pos += video_size_row;
683 }
684 need_wrap = 0;
685 }
686
687 static void ri(int currcons)
688 {
689
690
691
692 if (y == top)
693 scrdown(currcons,top,bottom);
694 else if (y > 0) {
695 y--;
696 pos -= video_size_row;
697 }
698 need_wrap = 0;
699 }
700
701 static inline void cr(int currcons)
702 {
703 pos -= x<<1;
704 need_wrap = x = 0;
705 }
706
707 static inline void bs(int currcons)
708 {
709 if (x) {
710 pos -= 2;
711 x--;
712 need_wrap = 0;
713 }
714 }
715
716 static inline void del(int currcons)
717 {
718
719 }
720
721 static void csi_J(int currcons, int vpar)
722 {
723 unsigned long count;
724 unsigned short * start;
725
726 switch (vpar) {
727 case 0:
728 count = (scr_end-pos)>>1;
729 start = (unsigned short *) pos;
730 break;
731 case 1:
732 count = ((pos-origin)>>1)+1;
733 start = (unsigned short *) origin;
734 break;
735 case 2:
736 count = video_num_columns * video_num_lines;
737 start = (unsigned short *) origin;
738 break;
739 default:
740 return;
741 }
742 while (count) {
743 count--;
744 scr_writew(video_erase_char, start++);
745 }
746 need_wrap = 0;
747 }
748
749 static void csi_K(int currcons, int vpar)
750 {
751 unsigned long count;
752 unsigned short * start;
753
754 switch (vpar) {
755 case 0:
756 count = video_num_columns-x;
757 start = (unsigned short *) pos;
758 break;
759 case 1:
760 start = (unsigned short *) (pos - (x<<1));
761 count = x+1;
762 break;
763 case 2:
764 start = (unsigned short *) (pos - (x<<1));
765 count = video_num_columns;
766 break;
767 default:
768 return;
769 }
770 while (count) {
771 count--;
772 scr_writew(video_erase_char, start++);
773 }
774 need_wrap = 0;
775 }
776
777 static void csi_X(int currcons, int vpar)
778 {
779 unsigned long count;
780 unsigned short * start;
781
782 if (!vpar)
783 vpar++;
784
785 start = (unsigned short *) pos;
786 count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
787
788 while (count) {
789 count--;
790 scr_writew(video_erase_char, start++);
791 }
792 need_wrap = 0;
793 }
794
795 static void update_attr(int currcons)
796 {
797 attr = color;
798 if (can_do_color) {
799 if (underline)
800 attr = (attr & 0xf0) | ulcolor;
801 else if (intensity == 0)
802 attr = (attr & 0xf0) | halfcolor;
803 }
804 if (reverse ^ decscnm)
805 attr = reverse_video_char(attr);
806 if (blink)
807 attr ^= 0x80;
808 if (intensity == 2)
809 attr ^= 0x08;
810 if (!can_do_color) {
811 if (underline)
812 attr = (attr & 0xf8) | 0x01;
813 else if (intensity == 0)
814 attr = (attr & 0xf0) | 0x08;
815 }
816 if (decscnm)
817 video_erase_char = (reverse_video_char(color) << 8) | ' ';
818 else
819 video_erase_char = (color << 8) | ' ';
820 }
821
822 static void default_attr(int currcons)
823 {
824 intensity = 1;
825 underline = 0;
826 reverse = 0;
827 blink = 0;
828 color = def_color;
829 }
830
831 static void csi_m(int currcons)
832 {
833 int i;
834
835 for (i=0;i<=npar;i++)
836 switch (par[i]) {
837 case 0:
838 default_attr(currcons);
839 break;
840 case 1:
841 intensity = 2;
842 break;
843 case 2:
844 intensity = 0;
845 break;
846 case 4:
847 underline = 1;
848 break;
849 case 5:
850 blink = 1;
851 break;
852 case 7:
853 reverse = 1;
854 break;
855 case 10:
856
857
858
859
860 translate = set_translate(charset == 0
861 ? G0_charset
862 : G1_charset);
863 disp_ctrl = 0;
864 toggle_meta = 0;
865 break;
866 case 11:
867
868
869
870 translate = set_translate(IBMPC_MAP);
871 disp_ctrl = 1;
872 toggle_meta = 0;
873 break;
874 case 12:
875
876
877
878 translate = set_translate(IBMPC_MAP);
879 disp_ctrl = 1;
880 toggle_meta = 1;
881 break;
882 case 21:
883 case 22:
884 intensity = 1;
885 break;
886 case 24:
887 underline = 0;
888 break;
889 case 25:
890 blink = 0;
891 break;
892 case 27:
893 reverse = 0;
894 break;
895 case 38:
896
897
898
899
900 color = (def_color & 0x0f) | background;
901 underline = 1;
902 break;
903 case 39:
904
905
906
907
908 color = (def_color & 0x0f) | background;
909 underline = 0;
910 break;
911 case 49:
912 color = (def_color & 0xf0) | foreground;
913 break;
914 default:
915 if (par[i] >= 30 && par[i] <= 37)
916 color = color_table[par[i]-30]
917 | background;
918 else if (par[i] >= 40 && par[i] <= 47)
919 color = (color_table[par[i]-40]<<4)
920 | foreground;
921 break;
922 }
923 update_attr(currcons);
924 }
925
926 static void respond_string(const char * p, struct tty_struct * tty)
927 {
928 while (*p) {
929 tty_insert_flip_char(tty, *p, 0);
930 p++;
931 }
932 tty_schedule_flip(tty);
933 }
934
935 static void cursor_report(int currcons, struct tty_struct * tty)
936 {
937 char buf[40];
938
939 sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
940 respond_string(buf, tty);
941 }
942
943 static inline void status_report(struct tty_struct * tty)
944 {
945 respond_string("\033[0n", tty);
946 }
947
948 static inline void respond_ID(struct tty_struct * tty)
949 {
950 respond_string(VT102ID, tty);
951 }
952
953 void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
954 {
955 char buf[8];
956
957 sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
958 (char)('!' + mry));
959 respond_string(buf, tty);
960 }
961
962
963 int mouse_reporting(void)
964 {
965 int currcons = fg_console;
966
967 return report_mouse;
968 }
969
970 static inline unsigned short *screenpos(int currcons, int offset, int viewed)
971 {
972 unsigned short *p = (unsigned short *)(origin + offset);
973 if (viewed && currcons == fg_console)
974 p -= (__real_origin - __origin);
975 return p;
976 }
977
978
979 void invert_screen(int currcons, int offset, int count, int viewed)
980 {
981 unsigned short *p;
982
983 count /= 2;
984 p = screenpos(currcons, offset, viewed);
985 if (can_do_color)
986 while (count--) {
987 unsigned short old = scr_readw(p);
988 scr_writew(reverse_video_short(old), p);
989 p++;
990 }
991 else
992 while (count--) {
993 unsigned short old = scr_readw(p);
994 scr_writew(old ^ (((old & 0x0700) == 0x0100)
995 ? 0x7000 : 0x7700), p);
996 p++;
997 }
998 }
999
1000
1001 void complement_pos(int currcons, int offset)
1002 {
1003 static unsigned short *p = NULL;
1004 static unsigned short old = 0;
1005
1006 if (p)
1007 scr_writew(old, p);
1008 if (offset == -1)
1009 p = NULL;
1010 else {
1011 p = screenpos(currcons, offset, 1);
1012 old = scr_readw(p);
1013 scr_writew(old ^ 0x7700, p);
1014 }
1015 }
1016
1017
1018 unsigned short screen_word(int currcons, int offset, int viewed)
1019 {
1020 return scr_readw(screenpos(currcons, offset, viewed));
1021 }
1022
1023
1024 int scrw2glyph(unsigned short scr_word)
1025 {
1026 return ( video_mode_512ch )
1027 ? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
1028 : scr_word & 0x00ff;
1029 }
1030
1031
1032 unsigned short *screen_pos(int currcons, int w_offset, int viewed)
1033 {
1034 return screenpos(currcons, 2 * w_offset, viewed);
1035 }
1036
1037 void getconsxy(int currcons, char *p)
1038 {
1039 p[0] = x;
1040 p[1] = y;
1041 }
1042
1043 void putconsxy(int currcons, char *p)
1044 {
1045 gotoxy(currcons, p[0], p[1]);
1046 set_cursor(currcons);
1047 }
1048
1049 static void set_mode(int currcons, int on_off)
1050 {
1051 int i;
1052
1053 for (i=0; i<=npar; i++)
1054 if (ques) switch(par[i]) {
1055 case 1:
1056 if (on_off)
1057 set_kbd(decckm);
1058 else
1059 clr_kbd(decckm);
1060 break;
1061 case 3:
1062 deccolm = on_off;
1063 #if 0
1064 (void) vc_resize(video_num_lines, deccolm ? 132 : 80);
1065
1066
1067 #endif
1068 break;
1069 case 5:
1070 if (decscnm != on_off) {
1071 decscnm = on_off;
1072 invert_screen(currcons, 0, video_screen_size, 0);
1073 update_attr(currcons);
1074 }
1075 break;
1076 case 6:
1077 decom = on_off;
1078 gotoxy(currcons,0,0);
1079 break;
1080 case 7:
1081 decawm = on_off;
1082 break;
1083 case 8:
1084 if (on_off)
1085 set_kbd(decarm);
1086 else
1087 clr_kbd(decarm);
1088 break;
1089 case 9:
1090 report_mouse = on_off ? 1 : 0;
1091 break;
1092 case 25:
1093 deccm = on_off;
1094 set_cursor(currcons);
1095 break;
1096 case 1000:
1097 report_mouse = on_off ? 2 : 0;
1098 break;
1099 } else switch(par[i]) {
1100 case 3:
1101 disp_ctrl = on_off;
1102 break;
1103 case 4:
1104 decim = on_off;
1105 break;
1106 case 20:
1107 if (on_off)
1108 set_kbd(lnm);
1109 else
1110 clr_kbd(lnm);
1111 break;
1112 }
1113 }
1114
1115 static void setterm_command(int currcons)
1116 {
1117 switch(par[0]) {
1118 case 1:
1119 if (can_do_color && par[1] < 16) {
1120 ulcolor = color_table[par[1]];
1121 if (underline)
1122 update_attr(currcons);
1123 }
1124 break;
1125 case 2:
1126 if (can_do_color && par[1] < 16) {
1127 halfcolor = color_table[par[1]];
1128 if (intensity == 0)
1129 update_attr(currcons);
1130 }
1131 break;
1132 case 8:
1133 def_color = attr;
1134 default_attr(currcons);
1135 update_attr(currcons);
1136 break;
1137 case 9:
1138 blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
1139 poke_blanked_console();
1140 break;
1141 case 10:
1142 if (npar >= 1)
1143 bell_pitch = par[1];
1144 else
1145 bell_pitch = DEFAULT_BELL_PITCH;
1146 break;
1147 case 11:
1148 if (npar >= 1)
1149 bell_duration = (par[1] < 2000) ?
1150 par[1]*HZ/1000 : 0;
1151 else
1152 bell_duration = DEFAULT_BELL_DURATION;
1153 break;
1154 case 12:
1155 if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
1156 update_screen(par[1]-1);
1157 break;
1158 case 13:
1159 unblank_screen();
1160 break;
1161 case 14:
1162 vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
1163 break;
1164 }
1165 }
1166
1167 static void insert_char(int currcons)
1168 {
1169 unsigned int i = x;
1170 unsigned short tmp, old = video_erase_char;
1171 unsigned short * p = (unsigned short *) pos;
1172
1173 while (i++ < video_num_columns) {
1174 tmp = scr_readw(p);
1175 scr_writew(old, p);
1176 old = tmp;
1177 p++;
1178 }
1179 need_wrap = 0;
1180 }
1181
1182 static void insert_line(int currcons)
1183 {
1184 scrdown(currcons,y,bottom);
1185 need_wrap = 0;
1186 }
1187
1188 static void delete_char(int currcons)
1189 {
1190 unsigned int i = x;
1191 unsigned short * p = (unsigned short *) pos;
1192
1193 while (++i < video_num_columns) {
1194 scr_writew(scr_readw(p+1), p);
1195 p++;
1196 }
1197 scr_writew(video_erase_char, p);
1198 need_wrap = 0;
1199 }
1200
1201 static void delete_line(int currcons)
1202 {
1203 scrup(currcons,y,bottom);
1204 need_wrap = 0;
1205 }
1206
1207 static void csi_at(int currcons, unsigned int nr)
1208 {
1209 if (nr > video_num_columns)
1210 nr = video_num_columns;
1211 else if (!nr)
1212 nr = 1;
1213 while (nr--)
1214 insert_char(currcons);
1215 }
1216
1217 static void csi_L(int currcons, unsigned int nr)
1218 {
1219 if (nr > video_num_lines)
1220 nr = video_num_lines;
1221 else if (!nr)
1222 nr = 1;
1223 while (nr--)
1224 insert_line(currcons);
1225 }
1226
1227 static void csi_P(int currcons, unsigned int nr)
1228 {
1229 if (nr > video_num_columns)
1230 nr = video_num_columns;
1231 else if (!nr)
1232 nr = 1;
1233 while (nr--)
1234 delete_char(currcons);
1235 }
1236
1237 static void csi_M(int currcons, unsigned int nr)
1238 {
1239 if (nr > video_num_lines)
1240 nr = video_num_lines;
1241 else if (!nr)
1242 nr=1;
1243 while (nr--)
1244 delete_line(currcons);
1245 }
1246
1247 static void save_cur(int currcons)
1248 {
1249 saved_x = x;
1250 saved_y = y;
1251 s_intensity = intensity;
1252 s_underline = underline;
1253 s_blink = blink;
1254 s_reverse = reverse;
1255 s_charset = charset;
1256 s_color = color;
1257 saved_G0 = G0_charset;
1258 saved_G1 = G1_charset;
1259 }
1260
1261 static void restore_cur(int currcons)
1262 {
1263 gotoxy(currcons,saved_x,saved_y);
1264 intensity = s_intensity;
1265 underline = s_underline;
1266 blink = s_blink;
1267 reverse = s_reverse;
1268 charset = s_charset;
1269 color = s_color;
1270 G0_charset = saved_G0;
1271 G1_charset = saved_G1;
1272 translate = set_translate(charset ? G1_charset : G0_charset);
1273 update_attr(currcons);
1274 need_wrap = 0;
1275 }
1276
1277 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
1278 EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
1279 ESpalette };
1280
1281 static void reset_terminal(int currcons, int do_clear)
1282 {
1283 top = 0;
1284 bottom = video_num_lines;
1285 vc_state = ESnormal;
1286 ques = 0;
1287 translate = set_translate(LAT1_MAP);
1288 G0_charset = LAT1_MAP;
1289 G1_charset = GRAF_MAP;
1290 charset = 0;
1291 need_wrap = 0;
1292 report_mouse = 0;
1293 utf = 0;
1294 utf_count = 0;
1295
1296 disp_ctrl = 0;
1297 toggle_meta = 0;
1298
1299 decscnm = 0;
1300 decom = 0;
1301 decawm = 1;
1302 deccm = 1;
1303 decim = 0;
1304
1305 set_kbd(decarm);
1306 clr_kbd(decckm);
1307 clr_kbd(kbdapplic);
1308 clr_kbd(lnm);
1309 kbd_table[currcons].lockstate = 0;
1310 kbd_table[currcons].slockstate = 0;
1311 kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
1312 kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
1313 set_leds();
1314
1315 default_attr(currcons);
1316 update_attr(currcons);
1317
1318 tab_stop[0] = 0x01010100;
1319 tab_stop[1] =
1320 tab_stop[2] =
1321 tab_stop[3] =
1322 tab_stop[4] = 0x01010101;
1323
1324 bell_pitch = DEFAULT_BELL_PITCH;
1325 bell_duration = DEFAULT_BELL_DURATION;
1326
1327 gotoxy(currcons,0,0);
1328 save_cur(currcons);
1329 if (do_clear)
1330 csi_J(currcons,2);
1331 }
1332
1333
1334
1335
1336 static void con_stop(struct tty_struct *tty)
1337 {
1338 int console_num;
1339 if (!tty)
1340 return;
1341 console_num = MINOR(tty->device) - (tty->driver.minor_start);
1342 if (!vc_cons_allocated(console_num))
1343 return;
1344 set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1345 set_leds();
1346 }
1347
1348
1349
1350
1351 static void con_start(struct tty_struct *tty)
1352 {
1353 int console_num;
1354 if (!tty)
1355 return;
1356 console_num = MINOR(tty->device) - (tty->driver.minor_start);
1357 if (!vc_cons_allocated(console_num))
1358 return;
1359 clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1360 set_leds();
1361 }
1362
1363 static int con_write(struct tty_struct * tty, int from_user,
1364 const unsigned char *buf, int count)
1365 {
1366 int c, tc, ok, n = 0;
1367 unsigned int currcons;
1368 struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
1369
1370 currcons = vt->vc_num;
1371 if (!vc_cons_allocated(currcons)) {
1372
1373 static int error = 0;
1374 if (!error) {
1375 error = 1;
1376 printk("con_write: tty %d not allocated\n", currcons+1);
1377 }
1378 return 0;
1379 }
1380
1381 if (currcons == sel_cons)
1382 clear_selection();
1383
1384 disable_bh(CONSOLE_BH);
1385 while (!tty->stopped && count) {
1386 enable_bh(CONSOLE_BH);
1387 c = from_user ? get_user(buf) : *buf;
1388 buf++; n++; count--;
1389 disable_bh(CONSOLE_BH);
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(CONSOLE_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 static void console_bh(void)
1959 {
1960 if (want_console >= 0) {
1961 if (want_console != fg_console) {
1962 change_console(want_console);
1963
1964
1965
1966 }
1967 want_console = -1;
1968 }
1969 if (do_poke_blanked_console) {
1970 do_poke_blanked_console = 0;
1971 poke_blanked_console();
1972 }
1973 }
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985 unsigned long con_init(unsigned long kmem_start)
1986 {
1987 const char *display_desc = "????";
1988 int currcons = 0;
1989 int orig_x = ORIG_X;
1990 int orig_y = ORIG_Y;
1991
1992 memset(&console_driver, 0, sizeof(struct tty_driver));
1993 console_driver.magic = TTY_DRIVER_MAGIC;
1994 console_driver.name = "tty";
1995 console_driver.name_base = 1;
1996 console_driver.major = TTY_MAJOR;
1997 console_driver.minor_start = 1;
1998 console_driver.num = MAX_NR_CONSOLES;
1999 console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
2000 console_driver.init_termios = tty_std_termios;
2001 console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
2002 console_driver.refcount = &console_refcount;
2003 console_driver.table = console_table;
2004 console_driver.termios = console_termios;
2005 console_driver.termios_locked = console_termios_locked;
2006
2007 console_driver.open = con_open;
2008 console_driver.write = con_write;
2009 console_driver.write_room = con_write_room;
2010 console_driver.chars_in_buffer = con_chars_in_buffer;
2011 console_driver.ioctl = vt_ioctl;
2012 console_driver.stop = con_stop;
2013 console_driver.start = con_start;
2014 console_driver.throttle = con_throttle;
2015 console_driver.unthrottle = con_unthrottle;
2016
2017 if (tty_register_driver(&console_driver))
2018 panic("Couldn't register console driver\n");
2019
2020 con_setsize(ORIG_VIDEO_LINES, ORIG_VIDEO_COLS);
2021
2022 timer_table[BLANK_TIMER].fn = blank_screen;
2023 timer_table[BLANK_TIMER].expires = 0;
2024 if (blankinterval) {
2025 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2026 timer_active |= 1<<BLANK_TIMER;
2027 }
2028
2029 kmem_start = con_type_init(kmem_start, &display_desc);
2030
2031 hardscroll_enabled = (hardscroll_disabled_by_init ? 0 :
2032 (video_type == VIDEO_TYPE_EGAC
2033 || video_type == VIDEO_TYPE_VGAC
2034 || video_type == VIDEO_TYPE_EGAM));
2035 has_wrapped = 0 ;
2036
2037
2038
2039 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
2040 int j, k ;
2041
2042 vc_cons[currcons].d = (struct vc_data *) kmem_start;
2043 kmem_start += sizeof(struct vc_data);
2044 vt_cons[currcons] = (struct vt_struct *) kmem_start;
2045 kmem_start += sizeof(struct vt_struct);
2046 vc_scrbuf[currcons] = (unsigned short *) kmem_start;
2047 kmem_start += video_screen_size;
2048 kmalloced = 0;
2049 screenbuf_size = video_screen_size;
2050 vc_init(currcons, video_num_lines, video_num_columns, currcons);
2051 for (j=k=0; j<16; j++) {
2052 vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
2053 vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
2054 vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
2055 }
2056 }
2057
2058 currcons = fg_console = 0;
2059
2060 video_mem_start = video_mem_base;
2061 video_mem_end = video_mem_term;
2062 origin = video_mem_start;
2063 scr_end = video_mem_start + video_num_lines * video_size_row;
2064 gotoxy(currcons,orig_x,orig_y);
2065 set_origin(currcons);
2066 csi_J(currcons, 0);
2067
2068
2069
2070
2071
2072 printable = 1;
2073 if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC
2074 || video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC )
2075 {
2076 default_font_height = video_font_height = ORIG_VIDEO_POINTS;
2077
2078 video_scan_lines = video_font_height * video_num_lines;
2079
2080 #ifdef CONFIG_SERIAL_ECHO
2081 serial_echo_init(SERIAL_ECHO_PORT);
2082 #endif
2083
2084 printk("Console: %ld point font, %ld scans\n",
2085 video_font_height, video_scan_lines);
2086 }
2087
2088 printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
2089 can_do_color ? "colour" : "mono",
2090 display_desc, video_num_columns, video_num_lines,
2091 MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s",
2092 MAX_NR_CONSOLES);
2093
2094
2095
2096
2097
2098
2099
2100 if (video_type != VIDEO_TYPE_TGAC)
2101 register_console(console_print);
2102
2103 init_bh(CONSOLE_BH, console_bh);
2104 return kmem_start;
2105 }
2106
2107 void vesa_powerdown_screen(void)
2108 {
2109 timer_active &= ~(1<<BLANK_TIMER);
2110 timer_table[BLANK_TIMER].fn = unblank_screen;
2111
2112 vesa_powerdown();
2113 }
2114
2115 void do_blank_screen(int nopowersave)
2116 {
2117 int currcons;
2118
2119 #ifdef CONFIG_APM
2120 if (apm_display_blank())
2121 return;
2122 #endif
2123
2124 if (console_blanked)
2125 return;
2126
2127 if(vesa_off_interval && !nopowersave) {
2128 timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
2129 timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
2130 timer_active |= (1<<BLANK_TIMER);
2131 } else {
2132 timer_active &= ~(1<<BLANK_TIMER);
2133 timer_table[BLANK_TIMER].fn = unblank_screen;
2134 }
2135
2136
2137 currcons = fg_console;
2138 has_scrolled = 0;
2139 blank__origin = __origin;
2140 blank_origin = origin;
2141 set_origin(fg_console);
2142 get_scrmem(fg_console);
2143 unblank_origin = origin;
2144 memsetw((void *)blank_origin, BLANK,
2145 2*video_num_lines*video_num_columns);
2146 hide_cursor();
2147 console_blanked = fg_console + 1;
2148
2149 if(!nopowersave)
2150 vesa_blank();
2151 }
2152
2153 void do_unblank_screen(void)
2154 {
2155 int currcons;
2156 int resetorg;
2157 long offset;
2158
2159 #ifdef CONFIG_APM
2160 if (apm_display_unblank())
2161 return;
2162 #endif
2163
2164 if (!console_blanked)
2165 return;
2166 if (!vc_cons_allocated(fg_console)) {
2167
2168 printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
2169 return;
2170 }
2171 timer_table[BLANK_TIMER].fn = blank_screen;
2172 if (blankinterval) {
2173 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2174 timer_active |= 1<<BLANK_TIMER;
2175 }
2176
2177 currcons = fg_console;
2178 offset = 0;
2179 resetorg = 0;
2180 if (console_blanked == fg_console + 1 && origin == unblank_origin
2181 && !has_scrolled) {
2182
2183 resetorg = 1;
2184 offset = (blank_origin - video_mem_base)
2185 - (unblank_origin - video_mem_start);
2186 }
2187
2188 console_blanked = 0;
2189 set_scrmem(fg_console, offset);
2190 set_origin(fg_console);
2191 set_cursor(fg_console);
2192 if (resetorg)
2193 __set_origin(blank__origin);
2194
2195 vesa_unblank();
2196 }
2197
2198
2199
2200
2201
2202 static void blank_screen(void)
2203 {
2204 do_blank_screen(0);
2205 }
2206
2207 static void unblank_screen(void)
2208 {
2209 do_unblank_screen();
2210 }
2211
2212 void update_screen(int new_console)
2213 {
2214 static int lock = 0;
2215
2216 if (new_console == fg_console || lock)
2217 return;
2218 if (!vc_cons_allocated(new_console)) {
2219
2220 printk("update_screen: tty %d not allocated ??\n", new_console+1);
2221 return;
2222 }
2223 lock = 1;
2224
2225 clear_selection();
2226
2227 if (!console_blanked)
2228 get_scrmem(fg_console);
2229 else
2230 console_blanked = -1;
2231 fg_console = new_console;
2232
2233 set_scrmem(fg_console, 0);
2234 set_origin(fg_console);
2235 set_cursor(fg_console);
2236 set_leds();
2237 compute_shiftstate();
2238 lock = 0;
2239 }
2240
2241
2242
2243
2244 int con_open(struct tty_struct *tty, struct file * filp)
2245 {
2246 unsigned int idx;
2247 int i;
2248
2249 idx = MINOR(tty->device) - tty->driver.minor_start;
2250
2251 i = vc_allocate(idx);
2252 if (i)
2253 return i;
2254
2255 vt_cons[idx]->vc_num = idx;
2256 tty->driver_data = vt_cons[idx];
2257
2258 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2259 tty->winsize.ws_row = video_num_lines;
2260 tty->winsize.ws_col = video_num_columns;
2261 }
2262 return 0;
2263 }
2264
2265
2266
2267
2268
2269
2270
2271 int con_set_cmap (unsigned char *arg)
2272 {
2273 return set_get_cmap (arg,1);
2274 }
2275
2276 int con_get_cmap (unsigned char *arg)
2277 {
2278 return set_get_cmap (arg,0);
2279 }
2280
2281 void reset_palette (int currcons)
2282 {
2283 int j, k ;
2284 for (j=k=0; j<16; j++) {
2285 palette[k++] = default_red[j];
2286 palette[k++] = default_grn[j];
2287 palette[k++] = default_blu[j];
2288 }
2289 set_palette() ;
2290 }
2291
2292
2293
2294
2295
2296
2297
2298 int con_set_font (char *arg, int ch512)
2299 {
2300 int i;
2301
2302 i = set_get_font (arg,1,ch512);
2303 if ( !i ) {
2304 hashtable_contents_valid = 0;
2305 video_mode_512ch = ch512;
2306 console_charmask = ch512 ? 0x1ff : 0x0ff;
2307 }
2308 return i;
2309 }
2310
2311 int con_get_font (char *arg)
2312 {
2313 return set_get_font (arg,0,video_mode_512ch);
2314 }