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