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