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 c = from_user ? get_user(buf) : *buf;
1387 buf++; n++; count--;
1388
1389 if (utf) {
1390
1391
1392 if(c > 0x7f) {
1393 if (utf_count > 0 && (c & 0xc0) == 0x80) {
1394 utf_char = (utf_char << 6) | (c & 0x3f);
1395 utf_count--;
1396 if (utf_count == 0)
1397 tc = c = utf_char;
1398 else continue;
1399 } else {
1400 if ((c & 0xe0) == 0xc0) {
1401 utf_count = 1;
1402 utf_char = (c & 0x1f);
1403 } else if ((c & 0xf0) == 0xe0) {
1404 utf_count = 2;
1405 utf_char = (c & 0x0f);
1406 } else if ((c & 0xf8) == 0xf0) {
1407 utf_count = 3;
1408 utf_char = (c & 0x07);
1409 } else if ((c & 0xfc) == 0xf8) {
1410 utf_count = 4;
1411 utf_char = (c & 0x03);
1412 } else if ((c & 0xfe) == 0xfc) {
1413 utf_count = 5;
1414 utf_char = (c & 0x01);
1415 } else
1416 utf_count = 0;
1417 continue;
1418 }
1419 } else {
1420 tc = c;
1421 utf_count = 0;
1422 }
1423 } else {
1424 tc = translate[toggle_meta ? (c|0x80) : c];
1425 }
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436 ok = (tc && (c >= 32 || (!utf && !(((disp_ctrl ? CTRL_ALWAYS
1437 : CTRL_ACTION) >> c) & 1))));
1438
1439 if (vc_state == ESnormal && ok) {
1440
1441 tc = conv_uni_to_pc(tc);
1442 if ( tc == -4 )
1443 {
1444
1445
1446 tc = conv_uni_to_pc(0xfffd);
1447 }
1448 else if ( tc == -3 )
1449 {
1450
1451 tc = c;
1452 }
1453 if (tc & ~console_charmask)
1454 continue;
1455
1456 if (need_wrap) {
1457 cr(currcons);
1458 lf(currcons);
1459 }
1460 if (decim)
1461 insert_char(currcons);
1462 scr_writew( video_mode_512ch ?
1463 ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
1464 (tc & 0x0ff) : (attr << 8) + tc,
1465 (unsigned short *) pos);
1466 if (x == video_num_columns - 1)
1467 need_wrap = decawm;
1468 else {
1469 x++;
1470 pos+=2;
1471 }
1472 continue;
1473 }
1474
1475
1476
1477
1478
1479 switch (c) {
1480 case 7:
1481 if (bell_duration)
1482 kd_mksound(bell_pitch, bell_duration);
1483 continue;
1484 case 8:
1485 bs(currcons);
1486 continue;
1487 case 9:
1488 pos -= (x << 1);
1489 while (x < video_num_columns - 1) {
1490 x++;
1491 if (tab_stop[x >> 5] & (1 << (x & 31)))
1492 break;
1493 }
1494 pos += (x << 1);
1495 continue;
1496 case 10: case 11: case 12:
1497 lf(currcons);
1498 if (!is_kbd(lnm))
1499 continue;
1500 case 13:
1501 cr(currcons);
1502 continue;
1503 case 14:
1504 charset = 1;
1505 translate = set_translate(G1_charset);
1506 disp_ctrl = 1;
1507 continue;
1508 case 15:
1509 charset = 0;
1510 translate = set_translate(G0_charset);
1511 disp_ctrl = 0;
1512 continue;
1513 case 24: case 26:
1514 vc_state = ESnormal;
1515 continue;
1516 case 27:
1517 vc_state = ESesc;
1518 continue;
1519 case 127:
1520 del(currcons);
1521 continue;
1522 case 128+27:
1523 vc_state = ESsquare;
1524 continue;
1525 }
1526 switch(vc_state) {
1527 case ESesc:
1528 vc_state = ESnormal;
1529 switch (c) {
1530 case '[':
1531 vc_state = ESsquare;
1532 continue;
1533 case ']':
1534 vc_state = ESnonstd;
1535 continue;
1536 case '%':
1537 vc_state = ESpercent;
1538 continue;
1539 case 'E':
1540 cr(currcons);
1541 lf(currcons);
1542 continue;
1543 case 'M':
1544 ri(currcons);
1545 continue;
1546 case 'D':
1547 lf(currcons);
1548 continue;
1549 case 'H':
1550 tab_stop[x >> 5] |= (1 << (x & 31));
1551 continue;
1552 case 'Z':
1553 respond_ID(tty);
1554 continue;
1555 case '7':
1556 save_cur(currcons);
1557 continue;
1558 case '8':
1559 restore_cur(currcons);
1560 continue;
1561 case '(':
1562 vc_state = ESsetG0;
1563 continue;
1564 case ')':
1565 vc_state = ESsetG1;
1566 continue;
1567 case '#':
1568 vc_state = EShash;
1569 continue;
1570 case 'c':
1571 reset_terminal(currcons,1);
1572 continue;
1573 case '>':
1574 clr_kbd(kbdapplic);
1575 continue;
1576 case '=':
1577 set_kbd(kbdapplic);
1578 continue;
1579 }
1580 continue;
1581 case ESnonstd:
1582 if (c=='P') {
1583 for (npar=0; npar<NPAR; npar++)
1584 par[npar] = 0 ;
1585 npar = 0 ;
1586 vc_state = ESpalette;
1587 continue;
1588 } else if (c=='R') {
1589 reset_palette (currcons);
1590 vc_state = ESnormal;
1591 } else
1592 vc_state = ESnormal;
1593 continue;
1594 case ESpalette:
1595 if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
1596 par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
1597 if (npar==7) {
1598 int i = par[0]*3, j = 1;
1599 palette[i] = 16*par[j++];
1600 palette[i++] += par[j++];
1601 palette[i] = 16*par[j++];
1602 palette[i++] += par[j++];
1603 palette[i] = 16*par[j++];
1604 palette[i] += par[j];
1605 set_palette() ;
1606 vc_state = ESnormal;
1607 }
1608 } else
1609 vc_state = ESnormal;
1610 continue;
1611 case ESsquare:
1612 for(npar = 0 ; npar < NPAR ; npar++)
1613 par[npar] = 0;
1614 npar = 0;
1615 vc_state = ESgetpars;
1616 if (c == '[') {
1617 vc_state=ESfunckey;
1618 continue;
1619 }
1620 ques = (c=='?');
1621 if (ques)
1622 continue;
1623 case ESgetpars:
1624 if (c==';' && npar<NPAR-1) {
1625 npar++;
1626 continue;
1627 } else if (c>='0' && c<='9') {
1628 par[npar] *= 10;
1629 par[npar] += c-'0';
1630 continue;
1631 } else vc_state=ESgotpars;
1632 case ESgotpars:
1633 vc_state = ESnormal;
1634 switch(c) {
1635 case 'h':
1636 set_mode(currcons,1);
1637 continue;
1638 case 'l':
1639 set_mode(currcons,0);
1640 continue;
1641 case 'n':
1642 if (!ques)
1643 if (par[0] == 5)
1644 status_report(tty);
1645 else if (par[0] == 6)
1646 cursor_report(currcons,tty);
1647 continue;
1648 }
1649 if (ques) {
1650 ques = 0;
1651 continue;
1652 }
1653 switch(c) {
1654 case 'G': case '`':
1655 if (par[0]) par[0]--;
1656 gotoxy(currcons,par[0],y);
1657 continue;
1658 case 'A':
1659 if (!par[0]) par[0]++;
1660 gotoxy(currcons,x,y-par[0]);
1661 continue;
1662 case 'B': case 'e':
1663 if (!par[0]) par[0]++;
1664 gotoxy(currcons,x,y+par[0]);
1665 continue;
1666 case 'C': case 'a':
1667 if (!par[0]) par[0]++;
1668 gotoxy(currcons,x+par[0],y);
1669 continue;
1670 case 'D':
1671 if (!par[0]) par[0]++;
1672 gotoxy(currcons,x-par[0],y);
1673 continue;
1674 case 'E':
1675 if (!par[0]) par[0]++;
1676 gotoxy(currcons,0,y+par[0]);
1677 continue;
1678 case 'F':
1679 if (!par[0]) par[0]++;
1680 gotoxy(currcons,0,y-par[0]);
1681 continue;
1682 case 'd':
1683 if (par[0]) par[0]--;
1684 gotoxy(currcons,x,par[0]);
1685 continue;
1686 case 'H': case 'f':
1687 if (par[0]) par[0]--;
1688 if (par[1]) par[1]--;
1689 gotoxy(currcons,par[1],par[0]);
1690 continue;
1691 case 'J':
1692 csi_J(currcons,par[0]);
1693 continue;
1694 case 'K':
1695 csi_K(currcons,par[0]);
1696 continue;
1697 case 'L':
1698 csi_L(currcons,par[0]);
1699 continue;
1700 case 'M':
1701 csi_M(currcons,par[0]);
1702 continue;
1703 case 'P':
1704 csi_P(currcons,par[0]);
1705 continue;
1706 case 'c':
1707 if (!par[0])
1708 respond_ID(tty);
1709 continue;
1710 case 'g':
1711 if (!par[0])
1712 tab_stop[x >> 5] &= ~(1 << (x & 31));
1713 else if (par[0] == 3) {
1714 tab_stop[0] =
1715 tab_stop[1] =
1716 tab_stop[2] =
1717 tab_stop[3] =
1718 tab_stop[4] = 0;
1719 }
1720 continue;
1721 case 'm':
1722 csi_m(currcons);
1723 continue;
1724 case 'q':
1725
1726 if (par[0] < 4)
1727 setledstate(kbd_table + currcons,
1728 (par[0] < 3) ? par[0] : 4);
1729 continue;
1730 case 'r':
1731 if (!par[0])
1732 par[0]++;
1733 if (!par[1])
1734 par[1] = video_num_lines;
1735
1736 if (par[0] < par[1] &&
1737 par[1] <= video_num_lines) {
1738 top=par[0]-1;
1739 bottom=par[1];
1740 gotoxy(currcons,0,0);
1741 }
1742 continue;
1743 case 's':
1744 save_cur(currcons);
1745 continue;
1746 case 'u':
1747 restore_cur(currcons);
1748 continue;
1749 case 'X':
1750 csi_X(currcons, par[0]);
1751 continue;
1752 case '@':
1753 csi_at(currcons,par[0]);
1754 continue;
1755 case ']':
1756 setterm_command(currcons);
1757 continue;
1758 }
1759 continue;
1760 case ESpercent:
1761 vc_state = ESnormal;
1762 switch (c) {
1763 case '@':
1764 utf = 0;
1765 continue;
1766 case 'G':
1767 case '8':
1768 utf = 1;
1769 continue;
1770 }
1771 continue;
1772 case ESfunckey:
1773 vc_state = ESnormal;
1774 continue;
1775 case EShash:
1776 vc_state = ESnormal;
1777 if (c == '8') {
1778
1779 video_erase_char =
1780 (video_erase_char & 0xff00) | 'E';
1781 csi_J(currcons, 2);
1782 video_erase_char =
1783 (video_erase_char & 0xff00) | ' ';
1784 }
1785 continue;
1786 case ESsetG0:
1787 if (c == '0')
1788 G0_charset = GRAF_MAP;
1789 else if (c == 'B')
1790 G0_charset = LAT1_MAP;
1791 else if (c == 'U')
1792 G0_charset = IBMPC_MAP;
1793 else if (c == 'K')
1794 G0_charset = USER_MAP;
1795 if (charset == 0)
1796 translate = set_translate(G0_charset);
1797 vc_state = ESnormal;
1798 continue;
1799 case ESsetG1:
1800 if (c == '0')
1801 G1_charset = GRAF_MAP;
1802 else if (c == 'B')
1803 G1_charset = LAT1_MAP;
1804 else if (c == 'U')
1805 G1_charset = IBMPC_MAP;
1806 else if (c == 'K')
1807 G1_charset = USER_MAP;
1808 if (charset == 1)
1809 translate = set_translate(G1_charset);
1810 vc_state = ESnormal;
1811 continue;
1812 default:
1813 vc_state = ESnormal;
1814 }
1815 }
1816 if (vcmode != KD_GRAPHICS)
1817 set_cursor(currcons);
1818 enable_bh(CONSOLE_BH);
1819 return n;
1820 }
1821
1822 static int con_write_room(struct tty_struct *tty)
1823 {
1824 if (tty->stopped)
1825 return 0;
1826 return 4096;
1827 }
1828
1829 static int con_chars_in_buffer(struct tty_struct *tty)
1830 {
1831 return 0;
1832 }
1833
1834 void poke_blanked_console(void)
1835 {
1836 timer_active &= ~(1<<BLANK_TIMER);
1837 if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
1838 return;
1839 if (console_blanked) {
1840 timer_table[BLANK_TIMER].fn = unblank_screen;
1841 timer_table[BLANK_TIMER].expires = 0;
1842 timer_active |= 1<<BLANK_TIMER;
1843 } else if (blankinterval) {
1844 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1845 timer_active |= 1<<BLANK_TIMER;
1846 }
1847 }
1848
1849 void console_print(const char * b)
1850 {
1851 int currcons = fg_console;
1852 unsigned char c;
1853 static int printing = 0;
1854
1855 if (!printable || printing)
1856 return;
1857 printing = 1;
1858
1859 if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
1860 currcons = kmsg_redirect - 1;
1861
1862 if (!vc_cons_allocated(currcons)) {
1863
1864 printk("console_print: tty %d not allocated ??\n", currcons+1);
1865 return;
1866 }
1867
1868 #ifdef CONFIG_SERIAL_ECHO
1869 serial_echo_print(b);
1870 #endif
1871
1872 while ((c = *(b++)) != 0) {
1873 if (c == 10 || c == 13 || need_wrap) {
1874 if (c != 13)
1875 lf(currcons);
1876 cr(currcons);
1877 if (c == 10 || c == 13)
1878 continue;
1879 }
1880 if (c == 8) {
1881 bs(currcons);
1882 continue;
1883 }
1884 scr_writew((attr << 8) + c, (unsigned short *) pos);
1885 if (x == video_num_columns - 1) {
1886 need_wrap = 1;
1887 continue;
1888 }
1889 x++;
1890 pos+=2;
1891 }
1892 set_cursor(currcons);
1893 poke_blanked_console();
1894 printing = 0;
1895 }
1896
1897
1898
1899
1900
1901
1902 static void con_throttle(struct tty_struct *tty)
1903 {
1904 }
1905
1906 static void con_unthrottle(struct tty_struct *tty)
1907 {
1908 struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
1909
1910 wake_up_interruptible(&vt->paste_wait);
1911 }
1912
1913 static void vc_init(unsigned int currcons, unsigned long rows, unsigned long cols, int do_clear)
1914 {
1915 long base = (long) vc_scrbuf[currcons];
1916 int j, k ;
1917
1918 video_num_columns = cols;
1919 video_num_lines = rows;
1920 video_size_row = cols<<1;
1921 video_screen_size = video_num_lines * video_size_row;
1922
1923 pos = origin = video_mem_start = base;
1924 scr_end = base + video_screen_size;
1925 video_mem_end = base + video_screen_size;
1926 reset_vc(currcons);
1927 for (j=k=0; j<16; j++) {
1928 vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
1929 vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
1930 vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
1931 }
1932 def_color = 0x07;
1933 ulcolor = 0x0f;
1934 halfcolor = 0x08;
1935 vt_cons[currcons]->paste_wait = 0;
1936 reset_terminal(currcons, do_clear);
1937 }
1938
1939 static void con_setsize(unsigned long rows, unsigned long cols)
1940 {
1941 video_num_lines = rows;
1942 video_num_columns = cols;
1943 video_size_row = 2 * cols;
1944 video_screen_size = video_num_lines * video_size_row;
1945 }
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956 static void console_bh(void)
1957 {
1958 if (want_console >= 0) {
1959 if (want_console != fg_console) {
1960 change_console(want_console);
1961
1962
1963
1964 }
1965 want_console = -1;
1966 }
1967 if (do_poke_blanked_console) {
1968 do_poke_blanked_console = 0;
1969 poke_blanked_console();
1970 }
1971 }
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983 unsigned long con_init(unsigned long kmem_start)
1984 {
1985 const char *display_desc = "????";
1986 int currcons = 0;
1987 int orig_x = ORIG_X;
1988 int orig_y = ORIG_Y;
1989
1990 memset(&console_driver, 0, sizeof(struct tty_driver));
1991 console_driver.magic = TTY_DRIVER_MAGIC;
1992 console_driver.name = "tty";
1993 console_driver.name_base = 1;
1994 console_driver.major = TTY_MAJOR;
1995 console_driver.minor_start = 1;
1996 console_driver.num = MAX_NR_CONSOLES;
1997 console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
1998 console_driver.init_termios = tty_std_termios;
1999 console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
2000 console_driver.refcount = &console_refcount;
2001 console_driver.table = console_table;
2002 console_driver.termios = console_termios;
2003 console_driver.termios_locked = console_termios_locked;
2004
2005 console_driver.open = con_open;
2006 console_driver.write = con_write;
2007 console_driver.write_room = con_write_room;
2008 console_driver.chars_in_buffer = con_chars_in_buffer;
2009 console_driver.ioctl = vt_ioctl;
2010 console_driver.stop = con_stop;
2011 console_driver.start = con_start;
2012 console_driver.throttle = con_throttle;
2013 console_driver.unthrottle = con_unthrottle;
2014
2015 if (tty_register_driver(&console_driver))
2016 panic("Couldn't register console driver\n");
2017
2018 con_setsize(ORIG_VIDEO_LINES, ORIG_VIDEO_COLS);
2019
2020 timer_table[BLANK_TIMER].fn = blank_screen;
2021 timer_table[BLANK_TIMER].expires = 0;
2022 if (blankinterval) {
2023 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2024 timer_active |= 1<<BLANK_TIMER;
2025 }
2026
2027 kmem_start = con_type_init(kmem_start, &display_desc);
2028
2029 hardscroll_enabled = (hardscroll_disabled_by_init ? 0 :
2030 (video_type == VIDEO_TYPE_EGAC
2031 || video_type == VIDEO_TYPE_VGAC
2032 || video_type == VIDEO_TYPE_EGAM));
2033 has_wrapped = 0 ;
2034
2035
2036
2037 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
2038 int j, k ;
2039
2040 vc_cons[currcons].d = (struct vc_data *) kmem_start;
2041 kmem_start += sizeof(struct vc_data);
2042 vt_cons[currcons] = (struct vt_struct *) kmem_start;
2043 kmem_start += sizeof(struct vt_struct);
2044 vc_scrbuf[currcons] = (unsigned short *) kmem_start;
2045 kmem_start += video_screen_size;
2046 kmalloced = 0;
2047 screenbuf_size = video_screen_size;
2048 vc_init(currcons, video_num_lines, video_num_columns, currcons);
2049 for (j=k=0; j<16; j++) {
2050 vc_cons[currcons].d->vc_palette[k++] = default_red[j] ;
2051 vc_cons[currcons].d->vc_palette[k++] = default_grn[j] ;
2052 vc_cons[currcons].d->vc_palette[k++] = default_blu[j] ;
2053 }
2054 }
2055
2056 currcons = fg_console = 0;
2057
2058 video_mem_start = video_mem_base;
2059 video_mem_end = video_mem_term;
2060 origin = video_mem_start;
2061 scr_end = video_mem_start + video_num_lines * video_size_row;
2062 gotoxy(currcons,orig_x,orig_y);
2063 set_origin(currcons);
2064 csi_J(currcons, 0);
2065
2066
2067
2068
2069
2070 printable = 1;
2071 if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC
2072 || video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC )
2073 {
2074 default_font_height = video_font_height = ORIG_VIDEO_POINTS;
2075
2076 video_scan_lines = video_font_height * video_num_lines;
2077
2078 #ifdef CONFIG_SERIAL_ECHO
2079 serial_echo_init(SERIAL_ECHO_PORT);
2080 #endif
2081
2082 printk("Console: %ld point font, %ld scans\n",
2083 video_font_height, video_scan_lines);
2084 }
2085
2086 printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
2087 can_do_color ? "colour" : "mono",
2088 display_desc, video_num_columns, video_num_lines,
2089 MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s",
2090 MAX_NR_CONSOLES);
2091
2092
2093
2094
2095
2096
2097
2098 if (video_type != VIDEO_TYPE_TGAC)
2099 register_console(console_print);
2100
2101 init_bh(CONSOLE_BH, console_bh);
2102 return kmem_start;
2103 }
2104
2105 void vesa_powerdown_screen(void)
2106 {
2107 timer_active &= ~(1<<BLANK_TIMER);
2108 timer_table[BLANK_TIMER].fn = unblank_screen;
2109
2110 vesa_powerdown();
2111 }
2112
2113 void do_blank_screen(int nopowersave)
2114 {
2115 int currcons;
2116
2117 #ifdef CONFIG_APM
2118 if (apm_display_blank())
2119 return;
2120 #endif
2121
2122 if (console_blanked)
2123 return;
2124
2125 if(vesa_off_interval && !nopowersave) {
2126 timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
2127 timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
2128 timer_active |= (1<<BLANK_TIMER);
2129 } else {
2130 timer_active &= ~(1<<BLANK_TIMER);
2131 timer_table[BLANK_TIMER].fn = unblank_screen;
2132 }
2133
2134
2135 currcons = fg_console;
2136 has_scrolled = 0;
2137 blank__origin = __origin;
2138 blank_origin = origin;
2139 set_origin(fg_console);
2140 get_scrmem(fg_console);
2141 unblank_origin = origin;
2142 memsetw((void *)blank_origin, BLANK,
2143 2*video_num_lines*video_num_columns);
2144 hide_cursor();
2145 console_blanked = fg_console + 1;
2146
2147 if(!nopowersave)
2148 vesa_blank();
2149 }
2150
2151 void do_unblank_screen(void)
2152 {
2153 int currcons;
2154 int resetorg;
2155 long offset;
2156
2157 #ifdef CONFIG_APM
2158 if (apm_display_unblank())
2159 return;
2160 #endif
2161
2162 if (!console_blanked)
2163 return;
2164 if (!vc_cons_allocated(fg_console)) {
2165
2166 printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
2167 return;
2168 }
2169 timer_table[BLANK_TIMER].fn = blank_screen;
2170 if (blankinterval) {
2171 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2172 timer_active |= 1<<BLANK_TIMER;
2173 }
2174
2175 currcons = fg_console;
2176 offset = 0;
2177 resetorg = 0;
2178 if (console_blanked == fg_console + 1 && origin == unblank_origin
2179 && !has_scrolled) {
2180
2181 resetorg = 1;
2182 offset = (blank_origin - video_mem_base)
2183 - (unblank_origin - video_mem_start);
2184 }
2185
2186 console_blanked = 0;
2187 set_scrmem(fg_console, offset);
2188 set_origin(fg_console);
2189 set_cursor(fg_console);
2190 if (resetorg)
2191 __set_origin(blank__origin);
2192
2193 vesa_unblank();
2194 }
2195
2196
2197
2198
2199
2200 static void blank_screen(void)
2201 {
2202 do_blank_screen(0);
2203 }
2204
2205 static void unblank_screen(void)
2206 {
2207 do_unblank_screen();
2208 }
2209
2210 void update_screen(int new_console)
2211 {
2212 static int lock = 0;
2213
2214 if (new_console == fg_console || lock)
2215 return;
2216 if (!vc_cons_allocated(new_console)) {
2217
2218 printk("update_screen: tty %d not allocated ??\n", new_console+1);
2219 return;
2220 }
2221 lock = 1;
2222
2223 clear_selection();
2224
2225 if (!console_blanked)
2226 get_scrmem(fg_console);
2227 else
2228 console_blanked = -1;
2229 fg_console = new_console;
2230
2231 set_scrmem(fg_console, 0);
2232 set_origin(fg_console);
2233 set_cursor(fg_console);
2234 set_leds();
2235 compute_shiftstate();
2236 lock = 0;
2237 }
2238
2239
2240
2241
2242 int con_open(struct tty_struct *tty, struct file * filp)
2243 {
2244 unsigned int idx;
2245 int i;
2246
2247 idx = MINOR(tty->device) - tty->driver.minor_start;
2248
2249 i = vc_allocate(idx);
2250 if (i)
2251 return i;
2252
2253 vt_cons[idx]->vc_num = idx;
2254 tty->driver_data = vt_cons[idx];
2255
2256 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2257 tty->winsize.ws_row = video_num_lines;
2258 tty->winsize.ws_col = video_num_columns;
2259 }
2260 return 0;
2261 }
2262
2263
2264
2265
2266
2267
2268
2269 int con_set_cmap (unsigned char *arg)
2270 {
2271 return set_get_cmap (arg,1);
2272 }
2273
2274 int con_get_cmap (unsigned char *arg)
2275 {
2276 return set_get_cmap (arg,0);
2277 }
2278
2279 void reset_palette (int currcons)
2280 {
2281 int j, k ;
2282 for (j=k=0; j<16; j++) {
2283 palette[k++] = default_red[j];
2284 palette[k++] = default_grn[j];
2285 palette[k++] = default_blu[j];
2286 }
2287 set_palette() ;
2288 }
2289
2290
2291
2292
2293
2294
2295
2296 int con_set_font (char *arg, int ch512)
2297 {
2298 int i;
2299
2300 i = set_get_font (arg,1,ch512);
2301 if ( !i ) {
2302 hashtable_contents_valid = 0;
2303 video_mode_512ch = ch512;
2304 console_charmask = ch512 ? 0x1ff : 0x0ff;
2305 }
2306 return i;
2307 }
2308
2309 int con_get_font (char *arg)
2310 {
2311 return set_get_font (arg,0,video_mode_512ch);
2312 }