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