This source file includes following definitions.
- gotoxy
- __set_origin
- scrollback
- scrollfront
- set_origin
- hide_cursor
- set_cursor
- scrup
- scrdown
- lf
- ri
- cr
- bs
- del
- csi_J
- csi_K
- update_attr
- default_attr
- csi_m
- respond_string
- respond_num
- cursor_report
- status_report
- respond_ID
- invert_screen
- 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_write
- do_keyboard_interrupt
- memsetw
- console_print
- con_init
- kbdsave
- get_scrmem
- set_scrmem
- blank_screen
- unblank_screen
- update_screen
- do_screendump
- con_open
- highlight
- inword
- atedge
- limit
- set_selection
- paste_selection
- clear_selection
- set_get_font
- con_set_font
- con_get_font
- con_set_trans
- con_get_trans
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 #define CAN_LOAD_EGA_FONTS
41
42
43
44
45
46
47
48
49 #include <linux/sched.h>
50 #include <linux/timer.h>
51 #include <linux/tty.h>
52 #include <linux/config.h>
53 #include <linux/kernel.h>
54 #include <linux/string.h>
55 #include <linux/errno.h>
56 #include <linux/kd.h>
57
58 #include <asm/io.h>
59 #include <asm/system.h>
60 #include <asm/segment.h>
61
62 #include "kbd_kern.h"
63 #include "vt_kern.h"
64
65 #ifdef CONFIG_SELECTION
66 #include <linux/ctype.h>
67
68
69 int set_selection(const int arg);
70 int paste_selection(struct tty_struct *tty);
71 static void clear_selection(void);
72
73
74 #define SEL_BUFFER_SIZE TTY_BUF_SIZE
75 static int sel_cons;
76 static int sel_start = -1;
77 static int sel_end;
78 static char sel_buffer[SEL_BUFFER_SIZE] = { '\0' };
79 #endif
80
81 #define NPAR 16
82
83 extern void vt_init(void);
84 extern void register_console(void (*proc)(const char *));
85 extern void compute_shiftstate(void);
86
87 unsigned long video_num_columns;
88 unsigned long video_num_lines;
89
90 static unsigned char video_type;
91 static unsigned long video_mem_base;
92 static unsigned long video_mem_term;
93 static unsigned long video_size_row;
94 static unsigned char video_page;
95 static unsigned short video_port_reg;
96 static unsigned short video_port_val;
97 static int can_do_color = 0;
98 static int printable = 0;
99
100 static struct {
101 unsigned short vc_video_erase_char;
102 unsigned char vc_attr;
103 unsigned char vc_def_color;
104 unsigned char vc_color;
105 unsigned char vc_s_color;
106 unsigned char vc_ulcolor;
107 unsigned char vc_halfcolor;
108 unsigned long vc_origin;
109 unsigned long vc_scr_end;
110 unsigned long vc_pos;
111 unsigned long vc_x,vc_y;
112 unsigned long vc_top,vc_bottom;
113 unsigned long vc_state;
114 unsigned long vc_npar,vc_par[NPAR];
115 unsigned long vc_video_mem_start;
116 unsigned long vc_video_mem_end;
117 unsigned long vc_saved_x;
118 unsigned long vc_saved_y;
119
120 unsigned long vc_charset : 1;
121 unsigned long vc_s_charset : 1;
122 unsigned long vc_decscnm : 1;
123 unsigned long vc_decom : 1;
124 unsigned long vc_decawm : 1;
125 unsigned long vc_deccm : 1;
126 unsigned long vc_decim : 1;
127
128 unsigned long vc_intensity : 2;
129 unsigned long vc_underline : 1;
130 unsigned long vc_blink : 1;
131 unsigned long vc_reverse : 1;
132 unsigned long vc_s_intensity : 2;
133 unsigned long vc_s_underline : 1;
134 unsigned long vc_s_blink : 1;
135 unsigned long vc_s_reverse : 1;
136
137 unsigned long vc_ques : 1;
138 unsigned long vc_need_wrap : 1;
139 unsigned long vc_tab_stop[5];
140 unsigned char * vc_translate;
141 unsigned char * vc_G0_charset;
142 unsigned char * vc_G1_charset;
143 unsigned char * vc_saved_G0;
144 unsigned char * vc_saved_G1;
145
146 } vc_cons [NR_CONSOLES];
147
148 unsigned short *vc_scrbuf[NR_CONSOLES];
149 static unsigned short * vc_scrmembuf;
150 static int console_blanked = 0;
151
152 #define origin (vc_cons[currcons].vc_origin)
153 #define scr_end (vc_cons[currcons].vc_scr_end)
154 #define pos (vc_cons[currcons].vc_pos)
155 #define top (vc_cons[currcons].vc_top)
156 #define bottom (vc_cons[currcons].vc_bottom)
157 #define x (vc_cons[currcons].vc_x)
158 #define y (vc_cons[currcons].vc_y)
159 #define state (vc_cons[currcons].vc_state)
160 #define npar (vc_cons[currcons].vc_npar)
161 #define par (vc_cons[currcons].vc_par)
162 #define ques (vc_cons[currcons].vc_ques)
163 #define attr (vc_cons[currcons].vc_attr)
164 #define saved_x (vc_cons[currcons].vc_saved_x)
165 #define saved_y (vc_cons[currcons].vc_saved_y)
166 #define translate (vc_cons[currcons].vc_translate)
167 #define G0_charset (vc_cons[currcons].vc_G0_charset)
168 #define G1_charset (vc_cons[currcons].vc_G1_charset)
169 #define saved_G0 (vc_cons[currcons].vc_saved_G0)
170 #define saved_G1 (vc_cons[currcons].vc_saved_G1)
171 #define video_mem_start (vc_cons[currcons].vc_video_mem_start)
172 #define video_mem_end (vc_cons[currcons].vc_video_mem_end)
173 #define video_erase_char (vc_cons[currcons].vc_video_erase_char)
174 #define decscnm (vc_cons[currcons].vc_decscnm)
175 #define decom (vc_cons[currcons].vc_decom)
176 #define decawm (vc_cons[currcons].vc_decawm)
177 #define deccm (vc_cons[currcons].vc_deccm)
178 #define decim (vc_cons[currcons].vc_decim)
179 #define need_wrap (vc_cons[currcons].vc_need_wrap)
180 #define color (vc_cons[currcons].vc_color)
181 #define s_color (vc_cons[currcons].vc_s_color)
182 #define def_color (vc_cons[currcons].vc_def_color)
183 #define foreground (color & 0x0f)
184 #define background (color & 0xf0)
185 #define charset (vc_cons[currcons].vc_charset)
186 #define s_charset (vc_cons[currcons].vc_s_charset)
187 #define intensity (vc_cons[currcons].vc_intensity)
188 #define underline (vc_cons[currcons].vc_underline)
189 #define blink (vc_cons[currcons].vc_blink)
190 #define reverse (vc_cons[currcons].vc_reverse)
191 #define s_intensity (vc_cons[currcons].vc_s_intensity)
192 #define s_underline (vc_cons[currcons].vc_s_underline)
193 #define s_blink (vc_cons[currcons].vc_s_blink)
194 #define s_reverse (vc_cons[currcons].vc_s_reverse)
195 #define ulcolor (vc_cons[currcons].vc_ulcolor)
196 #define halfcolor (vc_cons[currcons].vc_halfcolor)
197 #define tab_stop (vc_cons[currcons].vc_tab_stop)
198 #define vcmode (vt_cons[currcons].vc_mode)
199 #define vtmode (vt_cons[currcons].vt_mode)
200 #define vtpid (vt_cons[currcons].vt_pid)
201 #define vtnewvt (vt_cons[currcons].vt_newvt)
202
203 #define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
204 #define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
205 #define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
206
207 #define decarm VC_REPEAT
208 #define decckm VC_CKMODE
209 #define kbdapplic VC_APPLIC
210 #define kbdraw VC_RAW
211 #define lnm VC_CRLF
212
213 int blankinterval = 10*60*HZ;
214 static int screen_size = 0;
215
216
217
218
219 #define VT100ID "\033[?1;2c"
220 #define VT102ID "\033[?6c"
221
222 static unsigned char * translations[] = {
223
224 (unsigned char *)
225 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
226 "\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
227 " !\"#$%&'()*+,-./0123456789:;<=>?"
228 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
229 "`abcdefghijklmnopqrstuvwxyz{|}~\0"
230 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
231 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
232 "\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
233 "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
234 "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
235 "\376\245\376\376\376\376\231\376\350\376\376\376\232\376\376\341"
236 "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
237 "\376\244\225\242\223\376\224\366\355\227\243\226\201\376\376\230",
238
239 (unsigned char *)
240 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
241 "\0\0\0\0\0\0\0\0\0\0\376\0\0\0\0\0"
242 " !\"#$%&'()*+,-./0123456789:;<=>?"
243 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
244 "\004\261\007\007\007\007\370\361\007\007\331\277\332\300\305\304"
245 "\304\304\137\137\303\264\301\302\263\363\362\343\330\234\007\0"
246 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
247 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
248 "\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
249 "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
250 "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
251 "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
252 "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
253 "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230",
254
255 (unsigned char *)
256 "\000\001\002\003\004\005\006\007\000\011\000\013\000\000\000\000"
257 "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
258 "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
259 "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
260 "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
261 "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
262 "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
263 "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
264 "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
265 "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
266 "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
267 "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
268 "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
269 "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
270 "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
271 "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377",
272
273 (unsigned char *)
274 "\000\001\002\003\004\005\006\007\010\011\000\013\000\000\016\017"
275 "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
276 "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
277 "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
278 "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
279 "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
280 "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
281 "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
282 "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
283 "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
284 "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
285 "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
286 "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
287 "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
288 "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
289 "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
290 };
291
292 #define NORM_TRANS (translations[0])
293 #define GRAF_TRANS (translations[1])
294 #define NULL_TRANS (translations[2])
295 #define USER_TRANS (translations[3])
296
297 static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
298 8,12,10,14, 9,13,11,15 };
299
300
301
302
303
304
305 static void gotoxy(int currcons, int new_x, int new_y)
306 {
307 int max_y;
308
309 if (new_x < 0)
310 x = 0;
311 else
312 if (new_x >= video_num_columns)
313 x = video_num_columns - 1;
314 else
315 x = new_x;
316 if (decom) {
317 new_y += top;
318 max_y = bottom;
319 } else
320 max_y = video_num_lines;
321 if (new_y < 0)
322 y = 0;
323 else
324 if (new_y >= max_y)
325 y = max_y - 1;
326 else
327 y = new_y;
328 pos = origin + y*video_size_row + (x<<1);
329 need_wrap = 0;
330 }
331
332
333
334
335 static unsigned short __real_origin;
336 static unsigned short __origin;
337
338 static inline void __set_origin(unsigned short offset)
339 {
340 unsigned long flags;
341 #ifdef CONFIG_SELECTION
342 clear_selection();
343 #endif
344 save_flags(flags); cli();
345 __origin = offset;
346 outb_p(12, video_port_reg);
347 outb_p(offset >> 8, video_port_val);
348 outb_p(13, video_port_reg);
349 outb_p(offset, video_port_val);
350 restore_flags(flags);
351 }
352
353 void scrollback(int lines)
354 {
355 if (!lines)
356 lines = video_num_lines/2;
357 lines *= video_num_columns;
358 lines = __origin - lines;
359 if (lines < 0)
360 lines = 0;
361 __set_origin(lines);
362 }
363
364 void scrollfront(int lines)
365 {
366 if (!lines)
367 lines = video_num_lines/2;
368 lines *= video_num_columns;
369 lines = __origin + lines;
370 if (lines > __real_origin)
371 lines = __real_origin;
372 __set_origin(lines);
373 }
374
375 static void set_origin(int currcons)
376 {
377 if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
378 return;
379 if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
380 return;
381 __real_origin = (origin-video_mem_base) >> 1;
382 __set_origin(__real_origin);
383 }
384
385
386
387
388 static inline void hide_cursor(void)
389 {
390
391
392
393 outb_p(14, video_port_reg);
394 outb_p(0xff&((video_mem_term-video_mem_base)>>9), video_port_val);
395 outb_p(15, video_port_reg);
396 outb_p(0xff&((video_mem_term-video_mem_base)>>1), video_port_val);
397 }
398
399 static inline void set_cursor(int currcons)
400 {
401 unsigned long flags;
402
403 if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
404 return;
405 if (__real_origin != __origin)
406 set_origin(__real_origin);
407 save_flags(flags); cli();
408 if (deccm) {
409 outb_p(14, video_port_reg);
410 outb_p(0xff&((pos-video_mem_base)>>9), video_port_val);
411 outb_p(15, video_port_reg);
412 outb_p(0xff&((pos-video_mem_base)>>1), video_port_val);
413 } else
414 hide_cursor();
415 restore_flags(flags);
416 }
417
418 static void scrup(int currcons, unsigned int t, unsigned int b)
419 {
420 int hardscroll = 1;
421
422 if (b > video_num_lines || t >= b)
423 return;
424 if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM)
425 hardscroll = 0;
426 else if (t || b != video_num_lines)
427 hardscroll = 0;
428 if (hardscroll) {
429 origin += video_size_row;
430 pos += video_size_row;
431 scr_end += video_size_row;
432 if (scr_end > video_mem_end) {
433 __asm__("cld\n\t"
434 "rep\n\t"
435 "movsl\n\t"
436 "movl _video_num_columns,%1\n\t"
437 "rep\n\t"
438 "stosw"
439 :
440 :"a" (video_erase_char),
441 "c" ((video_num_lines-1)*video_num_columns>>1),
442 "D" (video_mem_start),
443 "S" (origin)
444 :"cx","di","si");
445 scr_end -= origin-video_mem_start;
446 pos -= origin-video_mem_start;
447 origin = video_mem_start;
448 } else {
449 __asm__("cld\n\t"
450 "rep\n\t"
451 "stosw"
452 :
453 :"a" (video_erase_char),
454 "c" (video_num_columns),
455 "D" (scr_end-video_size_row)
456 :"cx","di");
457 }
458 set_origin(currcons);
459 } else {
460 __asm__("cld\n\t"
461 "rep\n\t"
462 "movsl\n\t"
463 "movl _video_num_columns,%%ecx\n\t"
464 "rep\n\t"
465 "stosw"
466 :
467 :"a" (video_erase_char),
468 "c" ((b-t-1)*video_num_columns>>1),
469 "D" (origin+video_size_row*t),
470 "S" (origin+video_size_row*(t+1))
471 :"cx","di","si");
472 }
473 }
474
475 static void scrdown(int currcons, unsigned int t, unsigned int b)
476 {
477 if (b > video_num_lines || t >= b)
478 return;
479 __asm__("std\n\t"
480 "rep\n\t"
481 "movsl\n\t"
482 "addl $2,%%edi\n\t"
483 "movl _video_num_columns,%%ecx\n\t"
484 "rep\n\t"
485 "stosw\n\t"
486 "cld"
487 :
488 :"a" (video_erase_char),
489 "c" ((b-t-1)*video_num_columns>>1),
490 "D" (origin+video_size_row*b-4),
491 "S" (origin+video_size_row*(b-1)-4)
492 :"ax","cx","di","si");
493 }
494
495 static void lf(int currcons)
496 {
497 if (y+1<bottom) {
498 y++;
499 pos += video_size_row;
500 return;
501 } else
502 scrup(currcons,top,bottom);
503 need_wrap = 0;
504 }
505
506 static void ri(int currcons)
507 {
508 if (y>top) {
509 y--;
510 pos -= video_size_row;
511 return;
512 } else
513 scrdown(currcons,top,bottom);
514 need_wrap = 0;
515 }
516
517 static inline void cr(int currcons)
518 {
519 pos -= x<<1;
520 need_wrap = x = 0;
521 }
522
523 static inline void bs(int currcons)
524 {
525 if (x) {
526 pos -= 2;
527 x--;
528 need_wrap = 0;
529 }
530 }
531
532 static inline void del(int currcons)
533 {
534 #if 0
535 if (x) {
536 if (!need_wrap) {
537 pos -= 2;
538 x--;
539 }
540 *(unsigned short *)pos = video_erase_char;
541 need_wrap = 0;
542 }
543 #endif
544 }
545
546 static void csi_J(int currcons, int vpar)
547 {
548 unsigned long count;
549 unsigned long start;
550
551 switch (vpar) {
552 case 0:
553 count = (scr_end-pos)>>1;
554 start = pos;
555 break;
556 case 1:
557 count = ((pos-origin)>>1)+1;
558 start = origin;
559 break;
560 case 2:
561 count = video_num_columns * video_num_lines;
562 start = origin;
563 break;
564 default:
565 return;
566 }
567 __asm__("cld\n\t"
568 "rep\n\t"
569 "stosw\n\t"
570 :
571 :"c" (count),
572 "D" (start),"a" (video_erase_char)
573 :"cx","di");
574 need_wrap = 0;
575 }
576
577 static void csi_K(int currcons, int vpar)
578 {
579 long count;
580 long start;
581
582 switch (vpar) {
583 case 0:
584 count = video_num_columns-x;
585 start = pos;
586 break;
587 case 1:
588 start = pos - (x<<1);
589 count = x+1;
590 break;
591 case 2:
592 start = pos - (x<<1);
593 count = video_num_columns;
594 break;
595 default:
596 return;
597 }
598 __asm__("cld\n\t"
599 "rep\n\t"
600 "stosw\n\t"
601 :
602 :"c" (count),
603 "D" (start),"a" (video_erase_char)
604 :"cx","di");
605 need_wrap = 0;
606 }
607
608
609
610
611 static void update_attr(int currcons)
612 {
613 attr = color;
614 if (can_do_color) {
615 if (underline)
616 attr = (attr & 0xf0) | ulcolor;
617 else if (intensity == 0)
618 attr = (attr & 0xf0) | halfcolor;
619 }
620 if (reverse ^ decscnm)
621 attr = (attr & 0x88) | (((attr >> 4) | (attr << 4)) & 0x77);
622 if (blink)
623 attr ^= 0x80;
624 if (intensity == 2)
625 attr ^= 0x08;
626 if (!can_do_color) {
627 if (underline)
628 attr = (attr & 0xf8) | 0x01;
629 else if (intensity == 0)
630 attr = (attr & 0xf0) | 0x08;
631 }
632 if (decscnm)
633 video_erase_char = (((color & 0x88) | (((color >> 4) | (color << 4)) & 0x77)) << 8) | ' ';
634 else
635 video_erase_char = (color << 8) | ' ';
636 }
637
638 static void default_attr(int currcons)
639 {
640 intensity = 1;
641 underline = 0;
642 reverse = 0;
643 blink = 0;
644 color = def_color;
645 }
646
647 static void csi_m(int currcons)
648 {
649 int i;
650
651 for (i=0;i<=npar;i++)
652 switch (par[i]) {
653 case 0:
654 default_attr(currcons);
655 break;
656 case 1:
657 intensity = 2;
658 break;
659 case 2:
660 intensity = 0;
661 break;
662 case 4:
663 underline = 1;
664 break;
665 case 5:
666 blink = 1;
667 break;
668 case 7:
669 reverse = 1;
670 break;
671 case 21:
672 case 22:
673 intensity = 1;
674 break;
675 case 24:
676 underline = 0;
677 break;
678 case 25:
679 blink = 0;
680 break;
681 case 27:
682 reverse = 0;
683 break;
684 case 39:
685 color = (def_color & 0x0f) | background;
686 break;
687 case 49:
688 color = (def_color & 0xf0) | foreground;
689 break;
690 default:
691 if (par[i] >= 30 && par[i] <= 37)
692 color = color_table[par[i]-30]
693 | background;
694 else if (par[i] >= 40 && par[i] <= 47)
695 color = (color_table[par[i]-40]<<4)
696 | foreground;
697 break;
698 }
699 update_attr(currcons);
700 }
701
702 static void respond_string(char * p, int currcons, struct tty_struct * tty)
703 {
704 while (*p) {
705 put_tty_queue(*p, &tty->read_q);
706 p++;
707 }
708 TTY_READ_FLUSH(tty);
709 }
710
711 static void respond_num(unsigned int n, int currcons, struct tty_struct * tty)
712 {
713 char buff[3];
714 int i = 0;
715
716 do {
717 buff[i++] = (n%10)+'0';
718 n /= 10;
719 } while(n && i < 3);
720 while (i--) {
721 put_tty_queue(buff[i], &tty->read_q);
722 }
723
724 }
725
726 static void cursor_report(int currcons, struct tty_struct * tty)
727 {
728 put_tty_queue('\033', &tty->read_q);
729 put_tty_queue('[', &tty->read_q);
730 respond_num(y + (decom ? top+1 : 1), currcons, tty);
731 put_tty_queue(';', &tty->read_q);
732 respond_num(x+1, currcons, tty);
733 put_tty_queue('R', &tty->read_q);
734 TTY_READ_FLUSH(tty);
735 }
736
737 static inline void status_report(int currcons, struct tty_struct * tty)
738 {
739 respond_string("\033[0n", currcons, tty);
740 }
741
742 static inline void respond_ID(int currcons, struct tty_struct * tty)
743 {
744 respond_string(VT102ID, currcons, tty);
745 }
746
747 static void invert_screen(int currcons) {
748 unsigned char *p;
749
750 if (can_do_color)
751 for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2)
752 *p = (*p & 0x88) | (((*p >> 4) | (*p << 4)) & 0x77);
753 else
754 for (p = (unsigned char *)origin+1; p < (unsigned char *)scr_end; p+=2)
755 *p ^= *p & 0x07 == 1 ? 0x70 : 0x77;
756 }
757
758 static void set_mode(int currcons, int on_off)
759 {
760 int i;
761
762 for (i=0; i<=npar; i++)
763 if (ques) switch(par[i]) {
764 case 1:
765 if (on_off)
766 set_kbd(decckm);
767 else
768 clr_kbd(decckm);
769 break;
770 case 3:
771 csi_J(currcons,2);
772 gotoxy(currcons,0,0);
773 break;
774 case 5:
775 if (decscnm != on_off) {
776 decscnm = on_off;
777 invert_screen(currcons);
778 update_attr(currcons);
779 }
780 break;
781 case 6:
782 decom = on_off;
783 gotoxy(currcons,0,0);
784 break;
785 case 7:
786 decawm = on_off;
787 break;
788 case 8:
789 if (on_off)
790 set_kbd(decarm);
791 else
792 clr_kbd(decarm);
793 break;
794 case 25:
795 deccm = on_off;
796 set_cursor(currcons);
797 break;
798 } else switch(par[i]) {
799 case 4:
800 decim = on_off;
801 break;
802 case 20:
803 if (on_off)
804 set_kbd(lnm);
805 else
806 clr_kbd(lnm);
807 break;
808 }
809 }
810
811 static void setterm_command(int currcons)
812 {
813 switch(par[0]) {
814 case 1:
815 if (can_do_color && par[1] < 16) {
816 ulcolor = color_table[par[1]];
817 if (underline)
818 update_attr(currcons);
819 }
820 break;
821 case 2:
822 if (can_do_color && par[1] < 16) {
823 halfcolor = color_table[par[1]];
824 if (intensity == 0)
825 update_attr(currcons);
826 }
827 break;
828 case 8:
829 def_color = attr;
830 default_attr(currcons);
831 update_attr(currcons);
832 break;
833 case 9:
834 blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
835 break;
836 }
837 }
838
839 static void insert_char(int currcons)
840 {
841 unsigned int i = x;
842 unsigned short tmp, old = video_erase_char;
843 unsigned short * p = (unsigned short *) pos;
844
845 while (i++ < video_num_columns) {
846 tmp = *p;
847 *p = old;
848 old = tmp;
849 p++;
850 }
851 need_wrap = 0;
852 }
853
854 static void insert_line(int currcons)
855 {
856 scrdown(currcons,y,bottom);
857 need_wrap = 0;
858 }
859
860 static void delete_char(int currcons)
861 {
862 unsigned int i = x;
863 unsigned short * p = (unsigned short *) pos;
864
865 while (++i < video_num_columns) {
866 *p = *(p+1);
867 p++;
868 }
869 *p = video_erase_char;
870 need_wrap = 0;
871 }
872
873 static void delete_line(int currcons)
874 {
875 scrup(currcons,y,bottom);
876 need_wrap = 0;
877 }
878
879 static void csi_at(int currcons, unsigned int nr)
880 {
881 if (nr > video_num_columns)
882 nr = video_num_columns;
883 else if (!nr)
884 nr = 1;
885 while (nr--)
886 insert_char(currcons);
887 }
888
889 static void csi_L(int currcons, unsigned int nr)
890 {
891 if (nr > video_num_lines)
892 nr = video_num_lines;
893 else if (!nr)
894 nr = 1;
895 while (nr--)
896 insert_line(currcons);
897 }
898
899 static void csi_P(int currcons, unsigned int nr)
900 {
901 if (nr > video_num_columns)
902 nr = video_num_columns;
903 else if (!nr)
904 nr = 1;
905 while (nr--)
906 delete_char(currcons);
907 }
908
909 static void csi_M(int currcons, unsigned int nr)
910 {
911 if (nr > video_num_lines)
912 nr = video_num_lines;
913 else if (!nr)
914 nr=1;
915 while (nr--)
916 delete_line(currcons);
917 }
918
919 static void save_cur(int currcons)
920 {
921 saved_x = x;
922 saved_y = y;
923 s_intensity = intensity;
924 s_underline = underline;
925 s_blink = blink;
926 s_reverse = reverse;
927 s_charset = charset;
928 s_color = color;
929 saved_G0 = G0_charset;
930 saved_G1 = G1_charset;
931 }
932
933 static void restore_cur(int currcons)
934 {
935 gotoxy(currcons,saved_x,saved_y);
936 intensity = s_intensity;
937 underline = s_underline;
938 blink = s_blink;
939 reverse = s_reverse;
940 charset = s_charset;
941 color = s_color;
942 G0_charset = saved_G0;
943 G1_charset = saved_G1;
944 translate = charset ? G1_charset : G0_charset;
945 update_attr(currcons);
946 need_wrap = 0;
947 }
948
949 enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
950 EShash, ESsetG0, ESsetG1, ESignore };
951
952 static void reset_terminal(int currcons, int do_clear)
953 {
954 top = 0;
955 bottom = video_num_lines;
956 state = ESnormal;
957 ques = 0;
958 translate = NORM_TRANS;
959 G0_charset = NORM_TRANS;
960 G1_charset = GRAF_TRANS;
961 charset = 0;
962 need_wrap = 0;
963
964 decscnm = 0;
965 decom = 0;
966 decawm = 1;
967 deccm = 1;
968 decim = 0;
969
970 set_kbd(decarm);
971 clr_kbd(decckm);
972 clr_kbd(kbdapplic);
973 clr_kbd(lnm);
974 kbd_table[currcons].lockstate = 0;
975 kbd_table[currcons].ledstate = kbd_table[currcons].default_ledstate;
976 set_leds();
977
978 default_attr(currcons);
979 update_attr(currcons);
980
981 tab_stop[0] = 0x01010100;
982 tab_stop[1] =
983 tab_stop[2] =
984 tab_stop[3] =
985 tab_stop[4] = 0x01010101;
986
987 if (do_clear) {
988 gotoxy(currcons,0,0);
989 csi_J(currcons,2);
990 save_cur(currcons);
991 }
992 }
993
994 void con_write(struct tty_struct * tty)
995 {
996 int c;
997 unsigned int currcons;
998
999 currcons = tty->line - 1;
1000 if (currcons >= NR_CONSOLES) {
1001 printk("con_write: illegal tty (%d)\n", currcons);
1002 return;
1003 }
1004 #ifdef CONFIG_SELECTION
1005
1006
1007 if (!EMPTY(&tty->write_q) && currcons == sel_cons)
1008 clear_selection();
1009 #endif
1010 disable_bh(KEYBOARD_BH);
1011 while (!tty->stopped && (c = get_tty_queue(&tty->write_q)) >= 0) {
1012 if (state == ESnormal && translate[c]) {
1013 if (need_wrap) {
1014 cr(currcons);
1015 lf(currcons);
1016 }
1017 if (decim)
1018 insert_char(currcons);
1019 c = translate[c];
1020 *(unsigned short *) pos = (attr << 8) + c;
1021 if (x == video_num_columns - 1)
1022 need_wrap = decawm;
1023 else {
1024 x++;
1025 pos+=2;
1026 }
1027 continue;
1028 }
1029
1030
1031
1032
1033
1034 switch (c) {
1035 case 7:
1036 kd_mksound(0x637, HZ/8);
1037 continue;
1038 case 8:
1039 bs(currcons);
1040 continue;
1041 case 9:
1042 pos -= (x << 1);
1043 while (x < video_num_columns - 1) {
1044 x++;
1045 if (tab_stop[x >> 5] & (1 << (x & 31)))
1046 break;
1047 }
1048 pos += (x << 1);
1049 continue;
1050 case 10: case 11: case 12:
1051 lf(currcons);
1052 if (!is_kbd(lnm))
1053 continue;
1054 case 13:
1055 cr(currcons);
1056 continue;
1057 case 14:
1058 charset = 1;
1059 translate = G1_charset;
1060 continue;
1061 case 15:
1062 charset = 0;
1063 translate = G0_charset;
1064 continue;
1065 case 24: case 26:
1066 state = ESnormal;
1067 continue;
1068 case 27:
1069 state = ESesc;
1070 continue;
1071 case 127:
1072 del(currcons);
1073 continue;
1074 case 128+27:
1075 state = ESsquare;
1076 continue;
1077 }
1078 switch(state) {
1079 case ESesc:
1080 state = ESnormal;
1081 switch (c) {
1082 case '[':
1083 state = ESsquare;
1084 continue;
1085 case 'E':
1086 cr(currcons);
1087 lf(currcons);
1088 continue;
1089 case 'M':
1090 ri(currcons);
1091 continue;
1092 case 'D':
1093 lf(currcons);
1094 continue;
1095 case 'H':
1096 tab_stop[x >> 5] |= (1 << (x & 31));
1097 continue;
1098 case 'Z':
1099 respond_ID(currcons,tty);
1100 continue;
1101 case '7':
1102 save_cur(currcons);
1103 continue;
1104 case '8':
1105 restore_cur(currcons);
1106 continue;
1107 case '(':
1108 state = ESsetG0;
1109 continue;
1110 case ')':
1111 state = ESsetG1;
1112 continue;
1113 case '#':
1114 state = EShash;
1115 continue;
1116 case 'c':
1117 reset_terminal(currcons,1);
1118 continue;
1119 case '>':
1120 clr_kbd(kbdapplic);
1121 continue;
1122 case '=':
1123 set_kbd(kbdapplic);
1124 continue;
1125 }
1126 continue;
1127 case ESsquare:
1128 for(npar = 0 ; npar < NPAR ; npar++)
1129 par[npar] = 0;
1130 npar = 0;
1131 state = ESgetpars;
1132 if (c == '[') {
1133 state=ESfunckey;
1134 continue;
1135 }
1136 ques = (c=='?');
1137 if (ques)
1138 continue;
1139 case ESgetpars:
1140 if (c==';' && npar<NPAR-1) {
1141 npar++;
1142 continue;
1143 } else if (c>='0' && c<='9') {
1144 par[npar] *= 10;
1145 par[npar] += c-'0';
1146 continue;
1147 } else state=ESgotpars;
1148 case ESgotpars:
1149 state = ESnormal;
1150 switch(c) {
1151 case 'h':
1152 set_mode(currcons,1);
1153 continue;
1154 case 'l':
1155 set_mode(currcons,0);
1156 continue;
1157 case 'n':
1158 if (!ques)
1159 if (par[0] == 5)
1160 status_report(currcons,tty);
1161 else if (par[0] == 6)
1162 cursor_report(currcons,tty);
1163 continue;
1164 }
1165 if (ques) {
1166 ques = 0;
1167 continue;
1168 }
1169 switch(c) {
1170 case 'G': case '`':
1171 if (par[0]) par[0]--;
1172 gotoxy(currcons,par[0],y);
1173 continue;
1174 case 'A':
1175 if (!par[0]) par[0]++;
1176 gotoxy(currcons,x,y-par[0]);
1177 continue;
1178 case 'B': case 'e':
1179 if (!par[0]) par[0]++;
1180 gotoxy(currcons,x,y+par[0]);
1181 continue;
1182 case 'C': case 'a':
1183 if (!par[0]) par[0]++;
1184 gotoxy(currcons,x+par[0],y);
1185 continue;
1186 case 'D':
1187 if (!par[0]) par[0]++;
1188 gotoxy(currcons,x-par[0],y);
1189 continue;
1190 case 'E':
1191 if (!par[0]) par[0]++;
1192 gotoxy(currcons,0,y+par[0]);
1193 continue;
1194 case 'F':
1195 if (!par[0]) par[0]++;
1196 gotoxy(currcons,0,y-par[0]);
1197 continue;
1198 case 'd':
1199 if (par[0]) par[0]--;
1200 gotoxy(currcons,x,par[0]);
1201 continue;
1202 case 'H': case 'f':
1203 if (par[0]) par[0]--;
1204 if (par[1]) par[1]--;
1205 gotoxy(currcons,par[1],par[0]);
1206 continue;
1207 case 'J':
1208 csi_J(currcons,par[0]);
1209 continue;
1210 case 'K':
1211 csi_K(currcons,par[0]);
1212 continue;
1213 case 'L':
1214 csi_L(currcons,par[0]);
1215 continue;
1216 case 'M':
1217 csi_M(currcons,par[0]);
1218 continue;
1219 case 'P':
1220 csi_P(currcons,par[0]);
1221 continue;
1222 case 'c':
1223 if (!par[0])
1224 respond_ID(currcons,tty);
1225 continue;
1226 case 'g':
1227 if (!par[0])
1228 tab_stop[x >> 5] &= ~(1 << (x & 31));
1229 else if (par[0] == 3) {
1230 tab_stop[0] =
1231 tab_stop[1] =
1232 tab_stop[2] =
1233 tab_stop[3] =
1234 tab_stop[4] = 0;
1235 }
1236 continue;
1237 case 'm':
1238 csi_m(currcons);
1239 continue;
1240 case 'r':
1241 if (!par[0])
1242 par[0]++;
1243 if (!par[1])
1244 par[1] = video_num_lines;
1245
1246 if (par[0] < par[1] &&
1247 par[1] <= video_num_lines) {
1248 top=par[0]-1;
1249 bottom=par[1];
1250 gotoxy(currcons,0,0);
1251 }
1252 continue;
1253 case 's':
1254 save_cur(currcons);
1255 continue;
1256 case 'u':
1257 restore_cur(currcons);
1258 continue;
1259 case '@':
1260 csi_at(currcons,par[0]);
1261 continue;
1262 case ']':
1263 setterm_command(currcons);
1264 continue;
1265 }
1266 continue;
1267 case ESfunckey:
1268 state = ESnormal;
1269 continue;
1270 case EShash:
1271 state = ESnormal;
1272 if (c == '8') {
1273
1274 video_erase_char =
1275 (video_erase_char & 0xff00) | 'E';
1276 csi_J(currcons, 2);
1277 video_erase_char =
1278 (video_erase_char & 0xff00) | ' ';
1279 }
1280 continue;
1281 case ESsetG0:
1282 if (c == '0')
1283 G0_charset = GRAF_TRANS;
1284 else if (c == 'B')
1285 G0_charset = NORM_TRANS;
1286 else if (c == 'U')
1287 G0_charset = NULL_TRANS;
1288 else if (c == 'K')
1289 G0_charset = USER_TRANS;
1290 if (charset == 0)
1291 translate = G0_charset;
1292 state = ESnormal;
1293 continue;
1294 case ESsetG1:
1295 if (c == '0')
1296 G1_charset = GRAF_TRANS;
1297 else if (c == 'B')
1298 G1_charset = NORM_TRANS;
1299 else if (c == 'U')
1300 G1_charset = NULL_TRANS;
1301 else if (c == 'K')
1302 G1_charset = USER_TRANS;
1303 if (charset == 1)
1304 translate = G1_charset;
1305 state = ESnormal;
1306 continue;
1307 default:
1308 state = ESnormal;
1309 }
1310 }
1311 if (vcmode != KD_GRAPHICS)
1312 set_cursor(currcons);
1313 enable_bh(KEYBOARD_BH);
1314 if (LEFT(&tty->write_q) > WAKEUP_CHARS)
1315 wake_up_interruptible(&tty->write_q.proc_list);
1316 }
1317
1318 void do_keyboard_interrupt(void)
1319 {
1320 TTY_READ_FLUSH(TTY_TABLE(0));
1321 timer_active &= ~(1<<BLANK_TIMER);
1322 if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
1323 return;
1324 if (console_blanked) {
1325 timer_table[BLANK_TIMER].expires = 0;
1326 timer_active |= 1<<BLANK_TIMER;
1327 } else if (blankinterval) {
1328 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1329 timer_active |= 1<<BLANK_TIMER;
1330 }
1331 }
1332
1333 void * memsetw(void * s,unsigned short c,int count)
1334 {
1335 __asm__("cld\n\t"
1336 "rep\n\t"
1337 "stosw"
1338 :
1339 :"a" (c),"D" (s),"c" (count)
1340 :"cx","di");
1341 return s;
1342 }
1343
1344 void console_print(const char * b)
1345 {
1346 int currcons = fg_console;
1347 unsigned char c;
1348
1349 if (!printable || currcons<0 || currcons>=NR_CONSOLES)
1350 return;
1351 while ((c = *(b++)) != 0) {
1352 if (c == 10 || c == 13 || need_wrap) {
1353 if (c != 13)
1354 lf(currcons);
1355 cr(currcons);
1356 if (c == 10 || c == 13)
1357 continue;
1358 }
1359 *(unsigned short *) pos = (attr << 8) + c;
1360 if (x == video_num_columns - 1) {
1361 need_wrap = 1;
1362 continue;
1363 }
1364 x++;
1365 pos+=2;
1366 }
1367 set_cursor(currcons);
1368 if (vt_cons[fg_console].vc_mode == KD_GRAPHICS)
1369 return;
1370 timer_active &= ~(1<<BLANK_TIMER);
1371 if (console_blanked) {
1372 timer_table[BLANK_TIMER].expires = 0;
1373 timer_active |= 1<<BLANK_TIMER;
1374 } else if (blankinterval) {
1375 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1376 timer_active |= 1<<BLANK_TIMER;
1377 }
1378 }
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390 long con_init(long kmem_start)
1391 {
1392 char *display_desc = "????";
1393 int currcons = 0;
1394 long base;
1395 int orig_x = ORIG_X;
1396 int orig_y = ORIG_Y;
1397
1398 vc_scrmembuf = (unsigned short *) kmem_start;
1399 video_num_columns = ORIG_VIDEO_COLS;
1400 video_size_row = video_num_columns * 2;
1401 video_num_lines = ORIG_VIDEO_LINES;
1402 video_page = ORIG_VIDEO_PAGE;
1403 screen_size = (video_num_lines * video_size_row);
1404 kmem_start += NR_CONSOLES * screen_size;
1405 timer_table[BLANK_TIMER].fn = blank_screen;
1406 timer_table[BLANK_TIMER].expires = 0;
1407 if (blankinterval) {
1408 timer_table[BLANK_TIMER].expires = jiffies+blankinterval;
1409 timer_active |= 1<<BLANK_TIMER;
1410 }
1411
1412 if (ORIG_VIDEO_MODE == 7)
1413 {
1414 video_mem_base = 0xb0000;
1415 video_port_reg = 0x3b4;
1416 video_port_val = 0x3b5;
1417 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
1418 {
1419 video_type = VIDEO_TYPE_EGAM;
1420 video_mem_term = 0xb8000;
1421 display_desc = "EGA+";
1422 }
1423 else
1424 {
1425 video_type = VIDEO_TYPE_MDA;
1426 video_mem_term = 0xb2000;
1427 display_desc = "*MDA";
1428 }
1429 }
1430 else
1431 {
1432 can_do_color = 1;
1433 video_mem_base = 0xb8000;
1434 video_port_reg = 0x3d4;
1435 video_port_val = 0x3d5;
1436 if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
1437 {
1438 video_type = VIDEO_TYPE_EGAC;
1439 video_mem_term = 0xc0000;
1440 display_desc = "EGA+";
1441 }
1442 else
1443 {
1444 video_type = VIDEO_TYPE_CGA;
1445 video_mem_term = 0xba000;
1446 display_desc = "*CGA";
1447 }
1448 }
1449
1450
1451
1452 base = (long)vc_scrmembuf;
1453 for (currcons = 0; currcons<NR_CONSOLES; currcons++) {
1454 pos = origin = video_mem_start = base;
1455 scr_end = video_mem_end = (base += screen_size);
1456 vc_scrbuf[currcons] = (unsigned short *) origin;
1457 vcmode = KD_TEXT;
1458 vtmode.mode = VT_AUTO;
1459 vtmode.waitv = 0;
1460 vtmode.relsig = 0;
1461 vtmode.acqsig = 0;
1462 vtmode.frsig = 0;
1463 vtpid = -1;
1464 vtnewvt = -1;
1465 clr_kbd(kbdraw);
1466 def_color = 0x07;
1467 ulcolor = 0x0f;
1468 halfcolor = 0x08;
1469 reset_terminal(currcons, currcons);
1470 }
1471 currcons = fg_console = 0;
1472
1473 video_mem_start = video_mem_base;
1474 video_mem_end = video_mem_term;
1475 origin = video_mem_start;
1476 scr_end = video_mem_start + video_num_lines * video_size_row;
1477 gotoxy(currcons,0,0);
1478 save_cur(currcons);
1479 gotoxy(currcons,orig_x,orig_y);
1480 update_screen(fg_console);
1481 printable = 1;
1482 printk("Console: %s %s %ldx%ld, %d virtual consoles\n",
1483 can_do_color?"colour":"mono",
1484 display_desc,
1485 video_num_columns,video_num_lines,
1486 NR_CONSOLES);
1487 register_console(console_print);
1488 return kmem_start;
1489 }
1490
1491
1492
1493
1494
1495 void kbdsave(int new_console)
1496 {
1497 }
1498
1499 static void get_scrmem(int currcons)
1500 {
1501 memcpy((void *)vc_scrbuf[currcons],(void *)origin, screen_size);
1502 video_mem_start = (unsigned long)vc_scrbuf[currcons];
1503 origin = video_mem_start;
1504 scr_end = video_mem_end = video_mem_start+screen_size;
1505 pos = origin + y*video_size_row + (x<<1);
1506 }
1507
1508 static void set_scrmem(int currcons)
1509 {
1510 #ifdef CONFIG_HGA
1511
1512
1513
1514
1515
1516
1517
1518 if (video_type == VIDEO_TYPE_MDA)
1519 {
1520 if (vcmode == KD_TEXT)
1521 {
1522
1523 int i;
1524 static char herc_txt_tbl[12] = {
1525 0x61,0x50,0x52,0x0f,0x19,6,0x19,0x19,2,0x0d,0x0b,0x0c };
1526 outb_p(0, 0x3bf);
1527 outb_p(0, 0x3b8);
1528 for ( i = 0 ; i < 12 ; i++ )
1529 {
1530 outb_p(i, 0x3b4);
1531 outb_p(herc_txt_tbl[i], 0x3b5);
1532 }
1533 }
1534 #define HGA_BLINKER_ON 0x20
1535 #define HGA_SCREEN_ON 8
1536
1537 outb_p(HGA_BLINKER_ON | HGA_SCREEN_ON, 0x3b8);
1538 }
1539 #endif CONFIG_HGA
1540
1541 video_mem_start = video_mem_base;
1542 video_mem_end = video_mem_term;
1543 origin = video_mem_start;
1544 scr_end = video_mem_start + screen_size;
1545 pos = origin + y*video_size_row + (x<<1);
1546 memcpy((void *)video_mem_base, (void *)vc_scrbuf[fg_console], screen_size);
1547 }
1548
1549 void blank_screen(void)
1550 {
1551 if (console_blanked)
1552 return;
1553 timer_table[BLANK_TIMER].fn = unblank_screen;
1554 get_scrmem(fg_console);
1555 hide_cursor();
1556 console_blanked = 1;
1557 memsetw((void *)video_mem_base, 0x0020, video_mem_term-video_mem_base );
1558 }
1559
1560 void unblank_screen(void)
1561 {
1562 if (!console_blanked)
1563 return;
1564 timer_table[BLANK_TIMER].fn = blank_screen;
1565 if (blankinterval) {
1566 timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
1567 timer_active |= 1<<BLANK_TIMER;
1568 }
1569 console_blanked = 0;
1570 set_scrmem(fg_console);
1571 set_origin(fg_console);
1572 set_cursor(fg_console);
1573 }
1574
1575 void update_screen(int new_console)
1576 {
1577 static int lock = 0;
1578
1579 if (new_console == fg_console || lock)
1580 return;
1581 lock = 1;
1582 kbdsave(new_console);
1583 get_scrmem(fg_console);
1584 fg_console = new_console;
1585 set_scrmem(fg_console);
1586 set_origin(fg_console);
1587 set_cursor(new_console);
1588 set_leds();
1589 compute_shiftstate();
1590 lock = 0;
1591 }
1592
1593 int do_screendump(int arg)
1594 {
1595 char *sptr, *buf = (char *)arg;
1596 int currcons, l;
1597
1598 if (!suser())
1599 return -EPERM;
1600 l = verify_area(VERIFY_WRITE, buf,2+video_num_columns*video_num_lines);
1601 if (l)
1602 return l;
1603 currcons = get_fs_byte(buf+1);
1604 if ((currcons<0) || (currcons>NR_CONSOLES))
1605 return -EIO;
1606 put_fs_byte((char)(video_num_lines),buf++);
1607 put_fs_byte((char)(video_num_columns),buf++);
1608 currcons = (currcons ? currcons-1 : fg_console);
1609 sptr = (char *) origin;
1610 for (l=video_num_lines*video_num_columns; l>0 ; l--, sptr++)
1611 put_fs_byte(*sptr++,buf++);
1612 return(0);
1613 }
1614
1615
1616
1617
1618
1619 int con_open(struct tty_struct *tty, struct file * filp)
1620 {
1621 tty->write = con_write;
1622 tty->ioctl = vt_ioctl;
1623 if (tty->line > NR_CONSOLES)
1624 return -ENODEV;
1625 return 0;
1626 }
1627
1628 #ifdef CONFIG_SELECTION
1629
1630 #define hwscroll_offset (currcons == fg_console ? ((__real_origin - __origin) << 1) : 0)
1631
1632
1633 static void highlight(const int currcons, const int s, const int e)
1634 {
1635 unsigned char *p, *p1, *p2;
1636
1637 p1 = (unsigned char *)origin - hwscroll_offset + s + 1;
1638 p2 = (unsigned char *)origin - hwscroll_offset + e + 1;
1639 if (p1 > p2)
1640 {
1641 p = p1;
1642 p1 = p2;
1643 p2 = p;
1644 }
1645 for (p = p1; p <= p2; p += 2)
1646 *p = (*p & 0x88) | ((*p << 4) & 0x70) | ((*p >> 4) & 0x07);
1647 }
1648
1649
1650 static inline int inword(const char c) { return (isalnum(c) || c == '_'); }
1651
1652
1653 static inline int atedge(const int p)
1654 {
1655 return (!(p % video_size_row) || !((p + 2) % video_size_row));
1656 }
1657
1658
1659 static inline short limit(const int v, const int l, const int u)
1660 {
1661 return (v < l) ? l : ((v > u) ? u : v);
1662 }
1663
1664
1665 int set_selection(const int arg)
1666 {
1667 unsigned short *args, xs, ys, xe, ye;
1668 int currcons = fg_console;
1669 int sel_mode, new_sel_start, new_sel_end, spc;
1670 char *bp, *obp, *spos;
1671 int i, ps, pe;
1672 char *off = (char *)origin - hwscroll_offset;
1673
1674 unblank_screen();
1675 args = (unsigned short *)(arg + 1);
1676 xs = get_fs_word(args++) - 1;
1677 ys = get_fs_word(args++) - 1;
1678 xe = get_fs_word(args++) - 1;
1679 ye = get_fs_word(args++) - 1;
1680 sel_mode = get_fs_word(args);
1681
1682 xs = limit(xs, 0, video_num_columns - 1);
1683 ys = limit(ys, 0, video_num_lines - 1);
1684 xe = limit(xe, 0, video_num_columns - 1);
1685 ye = limit(ye, 0, video_num_lines - 1);
1686 ps = ys * video_size_row + (xs << 1);
1687 pe = ye * video_size_row + (xe << 1);
1688
1689 if (ps > pe)
1690 {
1691 int tmp = ps;
1692 ps = pe;
1693 pe = tmp;
1694 }
1695
1696 switch (sel_mode)
1697 {
1698 case 0:
1699 default:
1700 new_sel_start = ps;
1701 new_sel_end = pe;
1702 break;
1703 case 1:
1704 spc = isspace(*(off + ps));
1705 for (new_sel_start = ps; ; ps -= 2)
1706 {
1707 if ((spc && !isspace(*(off + ps))) ||
1708 (!spc && !inword(*(off + ps))))
1709 break;
1710 new_sel_start = ps;
1711 if (!(ps % video_size_row))
1712 break;
1713 }
1714 spc = isspace(*(off + pe));
1715 for (new_sel_end = pe; ; pe += 2)
1716 {
1717 if ((spc && !isspace(*(off + pe))) ||
1718 (!spc && !inword(*(off + pe))))
1719 break;
1720 new_sel_end = pe;
1721 if (!((pe + 2) % video_size_row))
1722 break;
1723 }
1724 break;
1725 case 2:
1726 new_sel_start = ps - ps % video_size_row;
1727 new_sel_end = pe + video_size_row
1728 - pe % video_size_row - 2;
1729 break;
1730 }
1731
1732 if (new_sel_end > new_sel_start &&
1733 !atedge(new_sel_end) && isspace(*(off + new_sel_end)))
1734 {
1735 for (pe = new_sel_end + 2; ; pe += 2)
1736 {
1737 if (!isspace(*(off + pe)) || atedge(pe))
1738 break;
1739 }
1740 if (isspace(*(off + pe)))
1741 new_sel_end = pe;
1742 }
1743 if (sel_cons != currcons)
1744 {
1745 clear_selection();
1746 sel_cons = currcons;
1747 }
1748 if (sel_start == -1)
1749 highlight(sel_cons, new_sel_start, new_sel_end);
1750 else if (new_sel_start == sel_start)
1751 {
1752 if (new_sel_end == sel_end)
1753 return 0;
1754 else if (new_sel_end > sel_end)
1755 highlight(sel_cons, sel_end + 2, new_sel_end);
1756 else
1757 highlight(sel_cons, new_sel_end + 2, sel_end);
1758 }
1759 else if (new_sel_end == sel_end)
1760 {
1761 if (new_sel_start < sel_start)
1762 highlight(sel_cons, new_sel_start, sel_start - 2);
1763 else
1764 highlight(sel_cons, sel_start, new_sel_start - 2);
1765 }
1766 else
1767 {
1768 clear_selection();
1769 highlight(sel_cons, new_sel_start, new_sel_end);
1770 }
1771 sel_start = new_sel_start;
1772 sel_end = new_sel_end;
1773 obp = bp = sel_buffer;
1774 for (i = sel_start; i <= sel_end; i += 2)
1775 {
1776 spos = (char *)off + i;
1777 *bp++ = *spos;
1778 if (!isspace(*spos))
1779 obp = bp;
1780 if (! ((i + 2) % video_size_row))
1781 {
1782
1783
1784 if (obp != bp)
1785 {
1786 bp = obp;
1787 *bp++ = '\r';
1788 }
1789 obp = bp;
1790 }
1791
1792
1793 if (bp - sel_buffer > SEL_BUFFER_SIZE - 3)
1794 break;
1795 }
1796 *bp = '\0';
1797 return 0;
1798 }
1799
1800
1801
1802 int paste_selection(struct tty_struct *tty)
1803 {
1804 char *bp = sel_buffer;
1805
1806 if (! *bp)
1807 return 0;
1808 unblank_screen();
1809 while (*bp) {
1810 put_tty_queue(*bp, &tty->read_q);
1811 bp++;
1812 TTY_READ_FLUSH(tty);
1813 }
1814 return 0;
1815 }
1816
1817
1818
1819 static void clear_selection()
1820 {
1821 if (sel_start != -1)
1822 {
1823 highlight(sel_cons, sel_start, sel_end);
1824 sel_start = -1;
1825 }
1826 }
1827 #endif
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841 #define colourmap ((char *)0xa0000)
1842 #define blackwmap ((char *)0xb0000)
1843 #define cmapsz 8192
1844 #define seq_port_reg (0x3c4)
1845 #define seq_port_val (0x3c5)
1846 #define gr_port_reg (0x3ce)
1847 #define gr_port_val (0x3cf)
1848
1849 static int set_get_font(char * arg, int set)
1850 {
1851 #ifdef CAN_LOAD_EGA_FONTS
1852 int i;
1853 char *charmap;
1854 int beg;
1855
1856
1857
1858 if (video_type == VIDEO_TYPE_EGAC) {
1859 charmap = colourmap;
1860 beg = 0x0e;
1861 } else if (video_type == VIDEO_TYPE_EGAM) {
1862 charmap = blackwmap;
1863 beg = 0x0a;
1864 } else
1865 return -EINVAL;
1866
1867 i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
1868 if (i)
1869 return i;
1870
1871 cli();
1872 outb_p( 0x00, seq_port_reg );
1873 outb_p( 0x01, seq_port_val );
1874 outb_p( 0x02, seq_port_reg );
1875 outb_p( 0x04, seq_port_val );
1876 outb_p( 0x04, seq_port_reg );
1877 outb_p( 0x07, seq_port_val );
1878 outb_p( 0x00, seq_port_reg );
1879 outb_p( 0x03, seq_port_val );
1880
1881 outb_p( 0x04, gr_port_reg );
1882 outb_p( 0x02, gr_port_val );
1883 outb_p( 0x05, gr_port_reg );
1884 outb_p( 0x00, gr_port_val );
1885 outb_p( 0x06, gr_port_reg );
1886 outb_p( 0x00, gr_port_val );
1887 sti();
1888
1889 if (set)
1890 for (i=0; i<cmapsz ; i++)
1891 *(charmap+i) = get_fs_byte(arg+i);
1892 else
1893 for (i=0; i<cmapsz ; i++)
1894 put_fs_byte(*(charmap+i), arg+i);
1895
1896 cli();
1897 outb_p( 0x00, seq_port_reg );
1898 outb_p( 0x01, seq_port_val );
1899 outb_p( 0x02, seq_port_reg );
1900 outb_p( 0x03, seq_port_val );
1901 outb_p( 0x04, seq_port_reg );
1902 outb_p( 0x03, seq_port_val );
1903 outb_p( 0x00, seq_port_reg );
1904 outb_p( 0x03, seq_port_val );
1905
1906 outb_p( 0x04, gr_port_reg );
1907 outb_p( 0x00, gr_port_val );
1908 outb_p( 0x05, gr_port_reg );
1909 outb_p( 0x10, gr_port_val );
1910 outb_p( 0x06, gr_port_reg );
1911 outb_p( beg, gr_port_val );
1912 sti();
1913
1914 return 0;
1915 #else
1916 return -EINVAL;
1917 #endif
1918 }
1919
1920
1921
1922
1923
1924
1925
1926 int con_set_font (char *arg)
1927 {
1928 return set_get_font (arg,1);
1929 }
1930
1931 int con_get_font (char *arg)
1932 {
1933 return set_get_font (arg,0);
1934 }
1935
1936
1937
1938
1939
1940
1941 int con_set_trans(char * arg)
1942 {
1943 int i;
1944
1945 i = verify_area(VERIFY_READ, (void *)arg, E_TABSZ);
1946 if (i)
1947 return i;
1948
1949 for (i=0; i<E_TABSZ ; i++) USER_TRANS[i] = get_fs_byte(arg+i);
1950 USER_TRANS[012]=0;
1951 USER_TRANS[014]=0;
1952 USER_TRANS[015]=0;
1953 USER_TRANS[033]=0;
1954 return 0;
1955 }
1956
1957 int con_get_trans(char * arg)
1958 {
1959 int i;
1960
1961 i = verify_area(VERIFY_WRITE, (void *)arg, E_TABSZ);
1962 if (i)
1963 return i;
1964
1965 for (i=0; i<E_TABSZ ; i++) put_fs_byte(USER_TRANS[i],arg+i);
1966 return 0;
1967 }