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