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