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