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