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