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