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