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 && !utf && 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 enable_bh(CONSOLE_BH);
1586 c = from_user ? get_user(buf) : *buf;
1587 disable_bh(CONSOLE_BH);
1588 tc = translate[toggle_meta ? (c|0x80) : c];
1589 if (!tc ||
1590 !(c >= 32
1591 || !(((disp_ctrl ? CTRL_ALWAYS
1592 : CTRL_ACTION) >> c) & 1)))
1593 break;
1594 tc = conv_uni_to_pc(tc);
1595 if (tc == -4)
1596 tc = conv_uni_to_pc(0xfffd);
1597 else if (tc == -3)
1598 tc = c;
1599
1600 buf++; n++; count--;
1601 if (tc & ~console_charmask)
1602 continue;
1603
1604 *p++ = tc;
1605 *pos++ = tc | (attr << 8);
1606 ++putcs_count;
1607 ++nextx;
1608 if (nextx == cols ||
1609 putcs_count == sizeof (putcs_buf))
1610 break;
1611 }
1612
1613 sw->con_putcs(vc_cons[currcons].d,
1614 putcs_buf, putcs_count, y, x);
1615 if (nextx == cols) {
1616 pos--;
1617 x = cols-1;
1618 need_wrap = decawm;
1619 } else
1620 x += putcs_count;
1621 continue;
1622 }
1623
1624
1625 #endif
1626
1627 if (decim)
1628 insert_char(currcons);
1629 *pos = (attr << 8) + tc;
1630 if (currcons == fg_console)
1631 sw->con_putc(vc_cons[currcons].d,tc,y,x);
1632 if (x == cols - 1)
1633 need_wrap = decawm;
1634 else {
1635 pos++;
1636 x++;
1637 }
1638 continue;
1639 }
1640
1641
1642
1643
1644
1645 switch (c) {
1646 case 7:
1647 if (bell_duration)
1648 kd_mksound(bell_pitch, bell_duration);
1649 continue;
1650 case 8:
1651 bs(currcons);
1652 continue;
1653 case 9:
1654 pos -= x;
1655 while (x < cols - 1) {
1656 x++;
1657 if (tab_stop[x >> 5] & (1 << (x & 31)))
1658 break;
1659 }
1660 pos += x;
1661 continue;
1662 case 10: case 11: case 12:
1663 lf(currcons);
1664 if (!is_kbd(lnm))
1665 continue;
1666 case 13:
1667 cr(currcons);
1668 continue;
1669 case 14:
1670 charset = 1;
1671 translate = set_translate(G1_charset);
1672 disp_ctrl = 1;
1673 continue;
1674 case 15:
1675 charset = 0;
1676 translate = set_translate(G0_charset);
1677 disp_ctrl = 0;
1678 continue;
1679 case 24: case 26:
1680 vc_state = ESnormal;
1681 continue;
1682 case 27:
1683 vc_state = ESesc;
1684 continue;
1685 case 127:
1686 del(currcons);
1687 continue;
1688 case 128+27:
1689 vc_state = ESsquare;
1690 continue;
1691 }
1692 switch(vc_state) {
1693 case ESesc:
1694 vc_state = ESnormal;
1695 switch (c) {
1696 case '[':
1697 vc_state = ESsquare;
1698 continue;
1699 case ']':
1700 vc_state = ESnonstd;
1701 continue;
1702 case '%':
1703 vc_state = ESpercent;
1704 continue;
1705 case 'E':
1706 cr(currcons);
1707 lf(currcons);
1708 continue;
1709 case 'M':
1710 ri(currcons);
1711 continue;
1712 case 'D':
1713 lf(currcons);
1714 continue;
1715 case 'H':
1716 tab_stop[x >> 5] |= (1 << (x & 31));
1717 continue;
1718 case 'Z':
1719 respond_ID(tty);
1720 continue;
1721 case '7':
1722 save_cur(currcons);
1723 continue;
1724 case '8':
1725 restore_cur(currcons);
1726 continue;
1727 case '(':
1728 vc_state = ESsetG0;
1729 continue;
1730 case ')':
1731 vc_state = ESsetG1;
1732 continue;
1733 case '#':
1734 vc_state = EShash;
1735 continue;
1736 case 'c':
1737 reset_terminal(currcons,1);
1738 continue;
1739 case '>':
1740 clr_kbd(kbdapplic);
1741 continue;
1742 case '=':
1743 set_kbd(kbdapplic);
1744 continue;
1745 }
1746 continue;
1747 case ESnonstd:
1748 if (c=='P') {
1749 for (npar=0; npar<NPAR; npar++)
1750 par[npar] = 0 ;
1751 npar = 0 ;
1752 vc_state = ESpalette;
1753 continue;
1754 } else if (c=='R') {
1755 #if 0
1756 reset_palette (currcons);
1757 #endif
1758 vc_state = ESnormal;
1759 } else
1760 vc_state = ESnormal;
1761 continue;
1762 case ESpalette:
1763 if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
1764 par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
1765 if (npar==7) {
1766 #if 0
1767 int i = par[0]*3, j = 1;
1768 palette[i] = 16*par[j++];
1769 palette[i++] += par[j++];
1770 palette[i] = 16*par[j++];
1771 palette[i++] += par[j++];
1772 palette[i] = 16*par[j++];
1773 palette[i] += par[j];
1774 set_palette() ;
1775 #endif
1776 vc_state = ESnormal;
1777 }
1778 } else
1779 vc_state = ESnormal;
1780 continue;
1781 case ESsquare:
1782 for(npar = 0 ; npar < NPAR ; npar++)
1783 par[npar] = 0;
1784 npar = 0;
1785 vc_state = ESgetpars;
1786 if (c == '[') {
1787 vc_state=ESfunckey;
1788 continue;
1789 }
1790 ques = (c=='?');
1791 if (ques)
1792 continue;
1793 case ESgetpars:
1794 if (c==';' && npar<NPAR-1) {
1795 npar++;
1796 continue;
1797 } else if (c>='0' && c<='9') {
1798 par[npar] *= 10;
1799 par[npar] += c-'0';
1800 continue;
1801 } else vc_state=ESgotpars;
1802 case ESgotpars:
1803 vc_state = ESnormal;
1804 switch(c) {
1805 case 'h':
1806 set_mode(currcons,1);
1807 continue;
1808 case 'l':
1809 set_mode(currcons,0);
1810 continue;
1811 case 'n':
1812 if (!ques)
1813 if (par[0] == 5)
1814 status_report(tty);
1815 else if (par[0] == 6)
1816 cursor_report(currcons,tty);
1817 continue;
1818 }
1819 if (ques) {
1820 ques = 0;
1821 continue;
1822 }
1823 switch(c) {
1824 case 'G': case '`':
1825 if (par[0]) par[0]--;
1826 gotoxy(currcons,par[0],y);
1827 continue;
1828 case 'A':
1829 if (!par[0]) par[0]++;
1830 gotoxy(currcons,x,y-par[0]);
1831 continue;
1832 case 'B': case 'e':
1833 if (!par[0]) par[0]++;
1834 gotoxy(currcons,x,y+par[0]);
1835 continue;
1836 case 'C': case 'a':
1837 if (!par[0]) par[0]++;
1838 gotoxy(currcons,x+par[0],y);
1839 continue;
1840 case 'D':
1841 if (!par[0]) par[0]++;
1842 gotoxy(currcons,x-par[0],y);
1843 continue;
1844 case 'E':
1845 if (!par[0]) par[0]++;
1846 gotoxy(currcons,0,y+par[0]);
1847 continue;
1848 case 'F':
1849 if (!par[0]) par[0]++;
1850 gotoxy(currcons,0,y-par[0]);
1851 continue;
1852 case 'd':
1853 if (par[0]) par[0]--;
1854 gotoxy(currcons,x,par[0]);
1855 continue;
1856 case 'H': case 'f':
1857 if (par[0]) par[0]--;
1858 if (par[1]) par[1]--;
1859 gotoxy(currcons,par[1],par[0]);
1860 continue;
1861 case 'J':
1862 csi_J(currcons,par[0]);
1863 continue;
1864 case 'K':
1865 csi_K(currcons,par[0]);
1866 continue;
1867 case 'L':
1868 csi_L(currcons,par[0]);
1869 continue;
1870 case 'M':
1871 csi_M(currcons,par[0]);
1872 continue;
1873 case 'P':
1874 csi_P(currcons,par[0]);
1875 continue;
1876 case 'c':
1877 if (!par[0])
1878 respond_ID(tty);
1879 continue;
1880 case 'g':
1881 if (!par[0])
1882 tab_stop[x >> 5] &= ~(1 << (x & 31));
1883 else if (par[0] == 3) {
1884 tab_stop[0] =
1885 tab_stop[1] =
1886 tab_stop[2] =
1887 tab_stop[3] =
1888 tab_stop[4] = 0;
1889 }
1890 continue;
1891 case 'm':
1892 csi_m(currcons);
1893 continue;
1894 case 'q':
1895
1896 if (par[0] < 4)
1897 setledstate(kbd_table + currcons,
1898 (par[0] < 3) ? par[0] : 4);
1899 continue;
1900 case 'r':
1901 if (!par[0])
1902 par[0]++;
1903 if (!par[1])
1904 par[1] = rows;
1905
1906 if (par[0] < par[1] &&
1907 par[1] <= rows) {
1908 top=par[0]-1;
1909 bottom=par[1];
1910 gotoxy(currcons,0,0);
1911 }
1912 continue;
1913 case 's':
1914 save_cur(currcons);
1915 continue;
1916 case 'u':
1917 restore_cur(currcons);
1918 continue;
1919 case 'X':
1920 csi_X(currcons, par[0]);
1921 continue;
1922 case '@':
1923 csi_at(currcons,par[0]);
1924 continue;
1925 case ']':
1926 setterm_command(currcons);
1927 continue;
1928 }
1929 continue;
1930 case ESpercent:
1931 vc_state = ESnormal;
1932 switch (c) {
1933 case '@':
1934 utf = 0;
1935 continue;
1936 case 'G':
1937 case '8':
1938 utf = 1;
1939 continue;
1940 }
1941 continue;
1942 case ESfunckey:
1943 vc_state = ESnormal;
1944 continue;
1945 case EShash:
1946 vc_state = ESnormal;
1947 if (c == '8') {
1948
1949 video_erase_char =
1950 (video_erase_char & 0xff00) | 'E';
1951
1952
1953
1954
1955
1956 csi_J(currcons, 2);
1957 video_erase_char =
1958 (video_erase_char & 0xff00) | ' ';
1959 }
1960 continue;
1961 case ESsetG0:
1962 if (c == '0')
1963 G0_charset = GRAF_MAP;
1964 else if (c == 'B')
1965 G0_charset = LAT1_MAP;
1966 else if (c == 'U')
1967 G0_charset = IBMPC_MAP;
1968 else if (c == 'K')
1969 G0_charset = USER_MAP;
1970 if (charset == 0)
1971 translate = set_translate(G0_charset);
1972 vc_state = ESnormal;
1973 continue;
1974 case ESsetG1:
1975 if (c == '0')
1976 G1_charset = GRAF_MAP;
1977 else if (c == 'B')
1978 G1_charset = LAT1_MAP;
1979 else if (c == 'U')
1980 G1_charset = IBMPC_MAP;
1981 else if (c == 'K')
1982 G1_charset = USER_MAP;
1983 if (charset == 1)
1984 translate = set_translate(G1_charset);
1985 vc_state = ESnormal;
1986 continue;
1987 default:
1988 vc_state = ESnormal;
1989 }
1990 }
1991 if (vcmode != KD_GRAPHICS)
1992 set_cursor(currcons);
1993 enable_bh(CONSOLE_BH);
1994 return n;
1995 }
1996
1997 static int con_write_room(struct tty_struct *tty)
1998 {
1999 if (tty->stopped)
2000 return 0;
2001 return 4096;
2002 }
2003
2004 static int con_chars_in_buffer(struct tty_struct *tty)
2005 {
2006 return 0;
2007 }
2008
2009 void poke_blanked_console(void)
2010 {
2011 timer_active &= ~(1<<BLANK_TIMER);
2012 if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
2013 return;
2014 if (console_blanked) {
2015 timer_table[BLANK_TIMER].fn = unblank_screen;
2016 timer_table[BLANK_TIMER].expires = 0;
2017 timer_active |= 1<<BLANK_TIMER;
2018 } else if (blankinterval) {
2019 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2020 timer_active |= 1<<BLANK_TIMER;
2021 }
2022 }
2023
2024
2025
2026 void console_print(const char * b)
2027 {
2028 int currcons = fg_console;
2029 unsigned char c;
2030 const char *start = b;
2031 ushort count = 0;
2032 ushort myx = x;
2033 static int printing = 0;
2034
2035 if (!printable || printing)
2036 return;
2037 printing = 1;
2038
2039 if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
2040 currcons = kmsg_redirect - 1;
2041
2042 if (!vc_cons_allocated(currcons)) {
2043
2044 printk("console_print: tty %d not allocated ??\n", currcons+1);
2045 printing = 0;
2046 return;
2047 }
2048
2049
2050 hide_cursor(currcons);
2051
2052
2053
2054
2055 while ((c = *(b++)) != 0) {
2056 if (c == 10 || c == 13 || c == 8 || need_wrap) {
2057 if ((count = b - start - 1) > 0) {
2058 sw->con_putcs(vc_cons[currcons].d, start, count ,
2059 y, x);
2060 x += count;
2061 if (need_wrap)
2062 x--;
2063 }
2064
2065 if (c == 8) {
2066 bs(currcons);
2067 start = b;
2068 myx = x;
2069 continue;
2070 }
2071 if (c != 13)
2072 lf(currcons);
2073 cr(currcons);
2074
2075 if (c == 10 || c == 13) {
2076 start = b; myx = x; continue;
2077 }
2078
2079 start = b-1; myx = x;
2080 }
2081
2082 *pos = c | (attr << 8);
2083 if (myx == cols - 1) {
2084 need_wrap = 1;
2085 continue;
2086 }
2087 pos++;
2088 myx++;
2089 }
2090
2091 if ((count = b - start -1) > 0) {
2092 sw->con_putcs(vc_cons[currcons].d, start, count ,
2093 y, x);
2094 x += count;
2095 if (x == cols)
2096 {
2097 x--;
2098 need_wrap = 1;
2099 }
2100 }
2101
2102 set_cursor(currcons);
2103 poke_blanked_console();
2104 printing = 0;
2105 }
2106
2107
2108
2109
2110
2111
2112
2113 static void con_throttle(struct tty_struct *tty)
2114 {
2115 }
2116
2117 static void con_unthrottle(struct tty_struct *tty)
2118 {
2119 struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
2120
2121 wake_up_interruptible(&vt->paste_wait);
2122 }
2123
2124 static void vc_init(unsigned int currcons, int do_clear)
2125 {
2126 long base = (long) vc_scrbuf[currcons];
2127
2128 pos = (unsigned short *)(origin = (ulong)video_mem_start = base);
2129 scr_end = base + screenbuf_size;
2130 video_mem_end = base + screenbuf_size;
2131 reset_vc(currcons);
2132 def_color = 0x07;
2133 ulcolor = 0x0f;
2134 halfcolor = 0x08;
2135 vt_cons[currcons]->paste_wait = 0;
2136 reset_terminal(currcons, do_clear);
2137 }
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148 static void console_bh(void)
2149 {
2150 if (want_console >= 0) {
2151 if (want_console != fg_console) {
2152 change_console(want_console);
2153
2154
2155
2156 }
2157 want_console = -1;
2158 }
2159 if (do_poke_blanked_console) {
2160 do_poke_blanked_console = 0;
2161 poke_blanked_console();
2162 }
2163 }
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175 unsigned long con_init(unsigned long kmem_start)
2176 {
2177 char *display_desc = "????";
2178 unsigned int currcons = 0;
2179 extern int serial_debug;
2180
2181 memset(&console_driver, 0, sizeof(struct tty_driver));
2182 console_driver.magic = TTY_DRIVER_MAGIC;
2183 console_driver.name = "tty";
2184 console_driver.name_base = 1;
2185 console_driver.major = TTY_MAJOR;
2186 console_driver.minor_start = 1;
2187 console_driver.num = MAX_NR_CONSOLES;
2188 console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
2189 console_driver.init_termios = tty_std_termios;
2190 console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
2191 console_driver.refcount = &console_refcount;
2192 console_driver.table = console_table;
2193 console_driver.termios = console_termios;
2194 console_driver.termios_locked = console_termios_locked;
2195
2196 console_driver.open = con_open;
2197 console_driver.write = con_write;
2198 console_driver.write_room = con_write_room;
2199 console_driver.chars_in_buffer = con_chars_in_buffer;
2200 console_driver.ioctl = vt_ioctl;
2201 console_driver.stop = con_stop;
2202 console_driver.start = con_start;
2203 console_driver.throttle = con_throttle;
2204 console_driver.unthrottle = con_unthrottle;
2205
2206 if (tty_register_driver(&console_driver))
2207 panic("Couldn't register console driver\n");
2208
2209 kmem_start = conswitchp->con_startup (kmem_start, &display_desc);
2210
2211 timer_table[BLANK_TIMER].fn = blank_screen;
2212 timer_table[BLANK_TIMER].expires = 0;
2213 if (blankinterval) {
2214 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2215 timer_active |= 1<<BLANK_TIMER;
2216 }
2217
2218
2219
2220 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
2221 vc_cons[currcons].d = (struct vc_data *) kmem_start;
2222 kmem_start += sizeof(struct vc_data);
2223 vt_cons[currcons] = (struct vt_struct *) kmem_start;
2224 kmem_start += sizeof(struct vt_struct);
2225
2226
2227 sw = conswitchp;
2228 cons_num = currcons;
2229 sw->con_init (vc_cons[currcons].d);
2230 size_row = cols<<1;
2231 screenbuf_size = rows*size_row;
2232
2233 vc_scrbuf[currcons] = (unsigned short *) kmem_start;
2234 kmem_start += screenbuf_size;
2235 kmalloced = 0;
2236 vc_init(currcons, currcons);
2237 }
2238
2239 currcons = fg_console = 0;
2240
2241 gotoxy(currcons,0,0);
2242 csi_J(currcons, 0);
2243 printable = 1;
2244 update_screen(fg_console);
2245 sw->con_cursor(vc_cons[currcons].d, CM_DRAW);
2246 printable = 1;
2247
2248
2249 if (!serial_debug)
2250 register_console(console_print);
2251 printk("Console: %s %s %ldx%ld, %d virtual console%s (max %d)\n",
2252 can_do_color ? "colour":"mono",
2253 display_desc,
2254 cols,rows,
2255 MIN_NR_CONSOLES, (MIN_NR_CONSOLES == 1) ? "" : "s", MAX_NR_CONSOLES);
2256
2257 init_bh(CONSOLE_BH, console_bh);
2258 return kmem_start;
2259 }
2260
2261 void do_blank_screen(int nopowersave)
2262 {
2263 int currcons;
2264
2265 if (console_blanked)
2266 return;
2267
2268 if (!vc_cons_allocated(fg_console)) {
2269
2270 printk("blank_screen: tty %d not allocated ??\n", fg_console+1);
2271 return;
2272 }
2273
2274
2275 if (vt_cons[fg_console]->vc_mode == KD_TEXT) {
2276 timer_active &= ~(1<<BLANK_TIMER);
2277 timer_table[BLANK_TIMER].fn = unblank_screen;
2278
2279
2280
2281 currcons = fg_console;
2282 has_scrolled = 0;
2283 sw->con_blank (1);
2284 }
2285 else
2286 hide_cursor(fg_console);
2287 console_blanked = fg_console + 1;
2288 }
2289
2290 void do_unblank_screen(void)
2291 {
2292 int currcons;
2293
2294 if (!console_blanked)
2295 return;
2296 if (!vc_cons_allocated(fg_console)) {
2297
2298 printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
2299 return;
2300 }
2301 timer_table[BLANK_TIMER].fn = blank_screen;
2302 if (blankinterval) {
2303 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2304 timer_active |= 1<<BLANK_TIMER;
2305 }
2306
2307 currcons = fg_console;
2308 console_blanked = 0;
2309 if (sw->con_blank (0))
2310
2311 update_screen( fg_console );
2312 set_cursor (fg_console);
2313 }
2314
2315 void update_screen(int new_console)
2316 {
2317 int currcons = fg_console;
2318 int xx, yy, startx, attr_save;
2319 char buf[256], *bufp;
2320 unsigned short *p;
2321 static int lock = 0;
2322
2323 if ( lock)
2324 return;
2325 if (!vc_cons_allocated(new_console)) {
2326
2327 printk("update_screen: tty %d not allocated ??\n", new_console+1);
2328 return;
2329 }
2330 lock = 1;
2331
2332 clear_selection();
2333
2334 currcons = fg_console = new_console;
2335 sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
2336 sw->con_switch (vc_cons[new_console].d);
2337
2338 p = video_mem_start;
2339 attr_save = attr;
2340 for (yy = 0; yy < rows; yy++)
2341 {
2342 bufp = buf;
2343 for (startx = xx = 0; xx < cols; xx++)
2344 {
2345 if (attr != ((*p >> 8) & 0xff))
2346 {
2347 if (bufp > buf)
2348 sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
2349 yy, startx);
2350 startx = xx;
2351 bufp = buf;
2352 attr = (*p >> 8) & 0xff;
2353 }
2354 *bufp++ = *p++;
2355 if (bufp == buf + sizeof (buf))
2356 {
2357 sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
2358 yy, startx);
2359 startx = xx + 1;
2360 bufp = buf;
2361 }
2362 }
2363 if (bufp > buf)
2364 sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
2365 yy, startx);
2366 }
2367 set_cursor (currcons);
2368 attr = attr_save;
2369 set_leds();
2370 compute_shiftstate();
2371 lock = 0;
2372 }
2373
2374
2375
2376
2377
2378 static void blank_screen(void)
2379 {
2380 do_blank_screen(0);
2381 }
2382
2383 static void unblank_screen(void)
2384 {
2385 do_unblank_screen();
2386 }
2387
2388
2389
2390
2391 int con_open(struct tty_struct *tty, struct file * filp)
2392 {
2393 unsigned int currcons;
2394 int i;
2395
2396 currcons = MINOR(tty->device) - tty->driver.minor_start;
2397
2398 i = vc_allocate(currcons);
2399 if (i)
2400 return i;
2401
2402 vt_cons[currcons]->vc_num = currcons;
2403 tty->driver_data = vt_cons[currcons];
2404
2405 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2406 tty->winsize.ws_row = rows;
2407 tty->winsize.ws_col = cols;
2408 }
2409
2410 return 0;
2411 }
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425 #define colourmap ((char *)0xa0000)
2426
2427
2428 #define blackwmap ((char *)0xa0000)
2429 #define cmapsz 8192
2430 #define seq_port_reg (0x3c4)
2431 #define seq_port_val (0x3c5)
2432 #define gr_port_reg (0x3ce)
2433 #define gr_port_val (0x3cf)
2434
2435 static int set_get_font(char * arg, int set)
2436 {
2437 #ifdef CAN_LOAD_EGA_FONTS
2438 int i;
2439 char *charmap;
2440 int beg;
2441
2442
2443
2444 if (video_type == VIDEO_TYPE_EGAC) {
2445 charmap = colourmap;
2446 beg = 0x0e;
2447 } else if (video_type == VIDEO_TYPE_EGAM) {
2448 charmap = blackwmap;
2449 beg = 0x0a;
2450 } else
2451 return -EINVAL;
2452
2453 i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
2454 if (i)
2455 return i;
2456
2457 cli();
2458 outb_p( 0x00, seq_port_reg );
2459 outb_p( 0x01, seq_port_val );
2460 outb_p( 0x02, seq_port_reg );
2461 outb_p( 0x04, seq_port_val );
2462 outb_p( 0x04, seq_port_reg );
2463 outb_p( 0x07, seq_port_val );
2464 outb_p( 0x00, seq_port_reg );
2465 outb_p( 0x03, seq_port_val );
2466
2467 outb_p( 0x04, gr_port_reg );
2468 outb_p( 0x02, gr_port_val );
2469 outb_p( 0x05, gr_port_reg );
2470 outb_p( 0x00, gr_port_val );
2471 outb_p( 0x06, gr_port_reg );
2472 outb_p( 0x00, gr_port_val );
2473 sti();
2474
2475 if (set)
2476 memcpy_fromfs (charmap, arg, cmapsz);
2477 else
2478 memcpy_tofs (arg, charmap, cmapsz);
2479
2480 cli();
2481 outb_p( 0x00, seq_port_reg );
2482 outb_p( 0x01, seq_port_val );
2483 outb_p( 0x02, seq_port_reg );
2484 outb_p( 0x03, seq_port_val );
2485 outb_p( 0x04, seq_port_reg );
2486 outb_p( 0x03, seq_port_val );
2487 outb_p( 0x00, seq_port_reg );
2488 outb_p( 0x03, seq_port_val );
2489
2490 outb_p( 0x04, gr_port_reg );
2491 outb_p( 0x00, gr_port_val );
2492 outb_p( 0x05, gr_port_reg );
2493 outb_p( 0x10, gr_port_val );
2494 outb_p( 0x06, gr_port_reg );
2495 outb_p( beg, gr_port_val );
2496 sti();
2497
2498 return 0;
2499 #else
2500 return -EINVAL;
2501 #endif
2502 }
2503
2504
2505
2506
2507
2508
2509 int con_set_cmap (unsigned char *arg)
2510 {
2511 return -EINVAL;
2512 }
2513
2514 int con_get_cmap (unsigned char *arg)
2515 {
2516 return -EINVAL;
2517 }
2518
2519 void reset_palette(int currcons)
2520 {
2521 }
2522
2523 void set_palette(void)
2524 {
2525 }
2526
2527
2528
2529
2530
2531
2532
2533 int con_set_font (char *arg)
2534 {
2535 hashtable_contents_valid = 0;
2536 return set_get_font (arg,1);
2537 }
2538
2539 int con_get_font (char *arg)
2540 {
2541 return set_get_font (arg,0);
2542 }
2543
2544
2545
2546
2547
2548
2549
2550 int con_adjust_height(unsigned long fontheight)
2551 {
2552 return -EINVAL;
2553 }
2554
2555 void set_vesa_blanking(int arg)
2556 {
2557 }
2558
2559 unsigned long get_video_num_lines(unsigned int currcons)
2560 {
2561 return(rows);
2562 }
2563
2564 unsigned long get_video_num_columns(unsigned int currcons)
2565 {
2566 return(cols);
2567 }
2568
2569 unsigned long get_video_size_row(unsigned int currcons)
2570 {
2571 return(size_row);
2572 }