OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [i960/] [kernel/] [console.c] - Blame information for rev 1765

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
 
2
/*
3
 *  arch/i960/kernel/console.c
4
 *
5
 *  Copyright (C) 1999  Keith Adams <kma@cse.ogi.edu>
6
 *                      Oregon Graduate Institute
7
 *
8
 *  based on
9
 *  drivers/char/console.c
10
 *  Copyright (C) 1991, 1992  Linus Torvalds
11
 */
12
/*
13
 *      console.c
14
 *
15
 * This module exports the console io functions:
16
 *
17
 *     'void do_keyboard_interrupt(void)'
18
 *
19
 *     'int vc_allocate(unsigned int console)'
20
 *     'int vc_cons_allocated(unsigned int console)'
21
 *     'int vc_resize(unsigned long lines, unsigned long cols)'
22
 *     'int vc_resize_con(unsigned long lines, unsigned long cols,
23
 *                        unsigned int currcons)'
24
 *     'void vc_disallocate(unsigned int currcons)'
25
 *
26
 *     'unsigned long con_init(unsigned long)'
27
 *     'int con_open(struct tty_struct *tty, struct file * filp)'
28
 *     'void con_write(struct tty_struct * tty)'
29
 *     'void console_print(const char * b)'
30
 *     'void update_screen(int new_console)'
31
 *
32
 *     'void do_blank_screen(int)'
33
 *     'void do_unblank_screen(void)'
34
 *     'void poke_blanked_console(void)'
35
 *
36
 *     'unsigned short *screen_pos(int currcons, int w_offset, int viewed)'
37
 *     'void complement_pos(int currcons, int offset)'
38
 *     'void invert_screen(int currcons, int offset, int count, int shift)'
39
 *
40
 *     'void scrollback(int lines)'
41
 *     'void scrollfront(int lines)'
42
 *
43
 *     'int con_get_font(char *)'
44
 *     'int con_set_font(char *)'
45
 *
46
 *     'void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)'
47
 *     'int mouse_reporting(void)'
48
 *
49
 *     'unsigned long get_video_num_lines(unsigned int console)'
50
 *     'unsigned long get_video_num_columns(unsigned int console)'
51
 *     'unsigned long get_video_size_row(unsigned int console)'
52
 *
53
 * Hopefully this will be a rather complete VT102 implementation.
54
 *
55
 * Beeping thanks to John T Kohl.
56
 *
57
 * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
58
 *   Chars, and VT100 enhancements by Peter MacDonald.
59
 *
60
 * Copy and paste function by Andrew Haylett,
61
 *   some enhancements by Alessandro Rubini.
62
 *
63
 * User definable mapping table and font loading by Eugene G. Crosser,
64
 * <crosser@pccross.msk.su>
65
 *
66
 * Code to check for different video-cards mostly by Galen Hunt,
67
 * <g-hunt@ee.utah.edu>
68
 *
69
 * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
70
 * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
71
 *
72
 * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
73
 * Resizing of consoles, aeb, 940926
74
 *
75
 * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
76
 * <poe@daimi.aau.dk>
77
 *
78
 */
79
 
80
#include <linux/config.h>
81
#include <linux/sched.h>
82
#include <linux/timer.h>
83
#include <linux/interrupt.h>
84
#include <linux/tty.h>
85
#include <linux/tty_flip.h>
86
#include <linux/kernel.h>
87
#include <linux/string.h>
88
#include <linux/errno.h>
89
#include <linux/console.h>
90
#include <linux/kd.h>
91
#include <linux/malloc.h>
92
#include <linux/major.h>
93
#include <linux/mm.h>
94
#include <linux/ioport.h>
95
 
96
#include <asm/io.h>
97
#include <asm/segment.h>
98
#include <asm/system.h>
99
#include <asm/bitops.h>
100
 
101
#include "../../../drivers/char/kbd_kern.h"
102
#include "../../../drivers/char/vt_kern.h"
103
#include "../../../drivers/char/consolemap.h"
104
#include "../../../drivers/char/selection.h"
105
 
106
 
107
 
108
#ifndef MIN
109
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
110
#endif
111
 
112
struct tty_driver console_driver;
113
static int console_refcount;
114
static struct tty_struct *console_table[MAX_NR_CONSOLES];
115
static struct termios *console_termios[MAX_NR_CONSOLES];
116
static struct termios *console_termios_locked[MAX_NR_CONSOLES];
117
 
118
static void vc_init(unsigned int console, int do_clear);
119
 
120
static void update_attr(int currcons);
121
static void gotoxy(int currcons, int new_x, int new_y);
122
static void save_cur(int currcons);
123
static void blank_screen(void);
124
static void unblank_screen(void);
125
extern void change_console(unsigned int);
126
static inline void set_cursor(int currcons);
127
static void reset_terminal(int currcons, int do_clear);
128
extern void reset_vc(unsigned int new_console);
129
extern void vt_init(void);
130
extern void register_console(void (*proc)(const char *));
131
extern void vesa_blank(void);
132
extern void vesa_unblank(void);
133
extern void compute_shiftstate(void);
134
void poke_blanked_console(void);
135
void do_blank_screen(int);
136
 
137
unsigned long   video_num_lines;
138
unsigned long   video_num_columns;
139
unsigned long   video_size_row;
140
 
141
static int printable = 0;                        /* Is console ready for printing? */
142
unsigned long video_font_height;        /* Height of current screen font */
143
unsigned long video_scan_lines;         /* Number of scan lines on screen */
144
unsigned long default_font_height;      /* Height of default screen font */
145
int           video_mode_512ch = 0;      /* 512-character mode */
146
static unsigned short console_charmask = 0x0ff;
147
 
148
static unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
149
 
150
/* used by kbd_bh - set by keyboard_interrupt */
151
       int do_poke_blanked_console = 0;
152
       int console_blanked = 0;
153
static int blankinterval = 10*60*HZ;
154
static int vesa_off_interval = 0;
155
static int vesa_blank_mode = 0; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
156
 
157
static struct vc {
158
        struct vc_data *d;
159
 
160
        /* might add  scrmem, vt_struct, kbd  at some time,
161
           to have everything in one place - the disadvantage
162
           would be that vc_cons etc can no longer be static */
163
} vc_cons [MAX_NR_CONSOLES];
164
struct consw *conswitchp;
165
 
166
#define cols            (vc_cons[currcons].d->vc_cols)
167
#define rows            (vc_cons[currcons].d->vc_rows)
168
#define size_row        (vc_cons[currcons].d->vc_size_row)
169
#define screenbuf_size  (vc_cons[currcons].d->vc_screenbuf_size)
170
#define cons_num        (vc_cons[currcons].d->vc_num)
171
#define origin          (vc_cons[currcons].d->vc_origin)
172
#define scr_end         (vc_cons[currcons].d->vc_scr_end)
173
#define pos             (vc_cons[currcons].d->vc_pos)
174
#define top             (vc_cons[currcons].d->vc_top)
175
#define bottom          (vc_cons[currcons].d->vc_bottom)
176
#define x               (vc_cons[currcons].d->vc_x)
177
#define y               (vc_cons[currcons].d->vc_y)
178
#define vc_state        (vc_cons[currcons].d->vc_state)
179
#define npar            (vc_cons[currcons].d->vc_npar)
180
#define par             (vc_cons[currcons].d->vc_par)
181
#define ques            (vc_cons[currcons].d->vc_ques)
182
#define attr            (vc_cons[currcons].d->vc_attr)
183
#define saved_x         (vc_cons[currcons].d->vc_saved_x)
184
#define saved_y         (vc_cons[currcons].d->vc_saved_y)
185
#define translate       (vc_cons[currcons].d->vc_translate)
186
#define G0_charset      (vc_cons[currcons].d->vc_G0_charset)
187
#define G1_charset      (vc_cons[currcons].d->vc_G1_charset)
188
#define saved_G0        (vc_cons[currcons].d->vc_saved_G0)
189
#define saved_G1        (vc_cons[currcons].d->vc_saved_G1)
190
#define utf             (vc_cons[currcons].d->vc_utf)
191
#define utf_count       (vc_cons[currcons].d->vc_utf_count)
192
#define utf_char        (vc_cons[currcons].d->vc_utf_char)
193
#define video_mem_start (vc_cons[currcons].d->vc_video_mem_start)
194
#define video_mem_end   (vc_cons[currcons].d->vc_video_mem_end)
195
#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)     
196
#define disp_ctrl       (vc_cons[currcons].d->vc_disp_ctrl)
197
#define toggle_meta     (vc_cons[currcons].d->vc_toggle_meta)
198
#define decscnm         (vc_cons[currcons].d->vc_decscnm)
199
#define decom           (vc_cons[currcons].d->vc_decom)
200
#define decawm          (vc_cons[currcons].d->vc_decawm)
201
#define deccm           (vc_cons[currcons].d->vc_deccm)
202
#define decim           (vc_cons[currcons].d->vc_decim)
203
#define deccolm         (vc_cons[currcons].d->vc_deccolm)
204
#define need_wrap       (vc_cons[currcons].d->vc_need_wrap)
205
#define has_scrolled    (vc_cons[currcons].d->vc_has_scrolled)
206
#define kmalloced       (vc_cons[currcons].d->vc_kmalloced)
207
#define report_mouse    (vc_cons[currcons].d->vc_report_mouse)
208
#define can_do_color    (vc_cons[currcons].d->vc_can_do_color)
209
#define color           (vc_cons[currcons].d->vc_color)
210
#define s_color         (vc_cons[currcons].d->vc_s_color)
211
#define def_color       (vc_cons[currcons].d->vc_def_color)
212
#define foreground      (color & 0x0f)
213
#define background      (color & 0xf0)
214
#define charset         (vc_cons[currcons].d->vc_charset)
215
#define s_charset       (vc_cons[currcons].d->vc_s_charset)
216
#define intensity       (vc_cons[currcons].d->vc_intensity)
217
#define underline       (vc_cons[currcons].d->vc_underline)
218
#define blink           (vc_cons[currcons].d->vc_blink)
219
#define reverse         (vc_cons[currcons].d->vc_reverse)
220
#define s_intensity     (vc_cons[currcons].d->vc_s_intensity)
221
#define s_underline     (vc_cons[currcons].d->vc_s_underline)
222
#define s_blink         (vc_cons[currcons].d->vc_s_blink)
223
#define s_reverse       (vc_cons[currcons].d->vc_s_reverse)
224
#define ulcolor         (vc_cons[currcons].d->vc_ulcolor)
225
#define halfcolor       (vc_cons[currcons].d->vc_halfcolor)
226
#define tab_stop        (vc_cons[currcons].d->vc_tab_stop)
227
#define bell_pitch      (vc_cons[currcons].d->vc_bell_pitch)
228
#define bell_duration   (vc_cons[currcons].d->vc_bell_duration)
229
#define sw              (vc_cons[currcons].d->vc_sw)
230
 
231
#define vcmode          (vt_cons[currcons]->vc_mode)
232
#if 0 /* XXX */
233
#define vtmode          (vt_cons[currcons]->vt_mode)
234
#define vtpid           (vt_cons[currcons]->vt_pid)
235
#define vtnewvt         (vt_cons[currcons]->vt_newvt)
236
#endif
237
 
238
#define structsize      (sizeof(struct vc_data) + sizeof(struct vt_struct))
239
 
240
int vc_cons_allocated(unsigned int i)
241
{
242
        return (i < MAX_NR_CONSOLES && vc_cons[i].d);
243
}
244
 
245
int vc_allocate(unsigned int currcons)          /* return 0 on success */
246
{
247
        if (currcons >= MAX_NR_CONSOLES)
248
          return -ENODEV;
249
        if (!vc_cons[currcons].d) {
250
            long p, q;
251
 
252
            /* prevent users from taking too much memory */
253
            if (currcons >= MAX_NR_USER_CONSOLES && !suser())
254
              return -EPERM;
255
 
256
            /* due to the granularity of kmalloc, we waste some memory here */
257
            /* the alloc is done in two steps, to optimize the common situation
258
               of a 25x80 console (structsize=216, screenbuf_size=4000) */
259
            p = (long) kmalloc(structsize, GFP_KERNEL);
260
            if (!p)
261
                return -ENOMEM;
262
            vc_cons[currcons].d = (struct vc_data *) p;
263
            vt_cons[currcons] = (struct vt_struct *)(p+sizeof(struct vc_data));
264
 
265
            /* ++Geert: sw->con_init determines console size */
266
            sw = conswitchp;
267
            cons_num = currcons;
268
            sw->con_init (vc_cons[currcons].d);
269
            size_row = cols<<1;
270
            screenbuf_size = rows*size_row;
271
 
272
            q = (long) kmalloc(screenbuf_size, GFP_KERNEL);
273
            if (!q) {
274
                kfree_s((char *) p, structsize);
275
                vc_cons[currcons].d = NULL;
276
                return -ENOMEM;
277
            }
278
            vc_scrbuf[currcons] = (unsigned short *) q;
279
            kmalloced = 1;
280
            vc_init (currcons, 1);
281
        }
282
        return 0;
283
}
284
 
285
/*
286
 * Change # of rows and columns (0 means the size of fg_console)
287
 * [this is to be used together with some user program
288
 * like resize that changes the hardware videomode]
289
 */
290
int vc_resize(unsigned long lines, unsigned long columns)
291
{
292
        unsigned long cc, ll, ss, sr;
293
        unsigned long occ, oll, oss, osr;
294
        unsigned short *p;
295
        unsigned int currcons = fg_console, i;
296
        unsigned short *newscreens[MAX_NR_CONSOLES];
297
        long ol, nl, rlth, rrem;
298
 
299
        cc = (columns ? columns : cols);
300
        ll = (lines ? lines : rows);
301
        sr = cc << 1;
302
        ss = sr * ll;
303
 
304
        /*
305
         * Some earlier version had all consoles of potentially
306
         * different sizes, but that was really messy.
307
         * So now we only change if there is room for all consoles
308
         * of the same size.
309
         */
310
        for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
311
            if (!vc_cons_allocated(currcons))
312
              newscreens[currcons] = 0;
313
            else {
314
                p = (unsigned short *) kmalloc(ss, GFP_USER);
315
                if (!p) {
316
                    for (i = 0; i< currcons; i++)
317
                      if (newscreens[i])
318
                        kfree_s(newscreens[i], ss);
319
                    return -ENOMEM;
320
                }
321
                newscreens[currcons] = p;
322
            }
323
        }
324
 
325
#if 0 /* XXX */
326
        get_scrmem(fg_console);
327
#endif
328
 
329
        for (currcons = 0; currcons < MAX_NR_CONSOLES; currcons++) {
330
            if (!vc_cons_allocated(currcons))
331
              continue;
332
 
333
            oll = rows;
334
            occ = cols;
335
            osr = size_row;
336
            oss = screenbuf_size;
337
 
338
            rows = ll;
339
            cols = cc;
340
            size_row = sr;
341
            screenbuf_size = ss;
342
 
343
            rlth = MIN(osr, sr);
344
            rrem = sr - rlth;
345
            ol = origin;
346
            nl = (long) newscreens[currcons];
347
            if (ll < oll)
348
              ol += (oll - ll) * osr;
349
 
350
            update_attr(currcons);
351
            while (ol < scr_end) {
352
                /* ++Geert: TODO: Because the attributes have different meanings
353
                   on monochrome and color, they should really be converted if
354
                   can_do_color changes... */
355
                memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
356
                if (rrem)
357
                  memsetw((void *)(nl + rlth), video_erase_char, rrem);
358
                ol += osr;
359
                nl += sr;
360
            }
361
 
362
            if (kmalloced)
363
              kfree_s(vc_scrbuf[currcons], oss);
364
            vc_scrbuf[currcons] = newscreens[currcons];
365
            kmalloced = 1;
366
            screenbuf_size = ss;
367
 
368
            origin = (long) video_mem_start = vc_scrbuf[currcons];
369
            scr_end = video_mem_end = ((long) video_mem_start) + ss;
370
 
371
            if (scr_end > nl)
372
              memsetw((void *) nl, video_erase_char, scr_end - nl);
373
 
374
            /* do part of a reset_terminal() */
375
            top = 0;
376
            bottom = rows;
377
            gotoxy(currcons, x, y);
378
            save_cur(currcons);
379
        }
380
 
381
#if 0 /* XXX */
382
        set_scrmem(fg_console, 0);
383
        set_origin(fg_console);
384
#endif /* XXX */
385
        update_screen(fg_console);
386
        set_cursor(fg_console);
387
 
388
        return 0;
389
}
390
 
391
/*
392
 * ++Geert: Change # of rows and columns for one specific console.
393
 * Of course it's not messy to have all consoles of potentially different sizes,
394
 * except on PCish hardware :-)
395
 *
396
 * This is called by the low level console driver (arch/m68k/console/fbcon.c or
397
 * arch/m68k/console/txtcon.c)
398
 */
399
void vc_resize_con(unsigned long lines, unsigned long columns,
400
                   unsigned int currcons)
401
{
402
        unsigned long cc, ll, ss, sr;
403
        unsigned long occ, oll, oss, osr;
404
        unsigned short *newscreen;
405
        long ol, nl, rlth, rrem;
406
        struct winsize ws;
407
 
408
        if (!columns || !lines || currcons >= MAX_NR_CONSOLES)
409
            return;
410
 
411
        cc = columns;
412
        ll = lines;
413
        sr = cc << 1;
414
        ss = sr * ll;
415
 
416
        if (!vc_cons_allocated(currcons))
417
            newscreen = 0;
418
        else if (!(newscreen = (unsigned short *) kmalloc(ss, GFP_USER)))
419
            return;
420
 
421
        if (vc_cons_allocated(currcons)) {
422
            oll = rows;
423
            occ = cols;
424
            osr = size_row;
425
            oss = screenbuf_size;
426
 
427
            rows = ll;
428
            cols = cc;
429
            size_row = sr;
430
            screenbuf_size = ss;
431
 
432
            rlth = MIN(osr, sr);
433
            rrem = sr - rlth;
434
            ol = origin;
435
            nl = (long) newscreen;
436
            if (ll < oll)
437
              ol += (oll - ll) * osr;
438
 
439
            update_attr(currcons);
440
            while (ol < scr_end) {
441
                /* ++Geert: TODO: Because the attributes have different meanings
442
                   on monochrome and color, they should really be converted if
443
                   can_do_color changes... */
444
                memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
445
                if (rrem)
446
                  memsetw((void *)(nl + rlth), video_erase_char, rrem);
447
                ol += osr;
448
                nl += sr;
449
            }
450
 
451
            if (kmalloced)
452
              kfree_s(vc_scrbuf[currcons], oss);
453
            vc_scrbuf[currcons] = newscreen;
454
            kmalloced = 1;
455
            screenbuf_size = ss;
456
 
457
            origin = (long) video_mem_start = vc_scrbuf[currcons];
458
            scr_end = video_mem_end = ((long)video_mem_start) + ss;
459
 
460
            if (scr_end > nl)
461
              memsetw((void *) nl, video_erase_char, scr_end - nl);
462
 
463
            /* do part of a reset_terminal() */
464
            top = 0;
465
            bottom = rows;
466
            gotoxy(currcons, x, y);
467
            save_cur(currcons);
468
 
469
            ws.ws_row = rows;
470
            ws.ws_col = cols;
471
            if (memcmp(&ws, &console_table[currcons]->winsize, sizeof (struct winsize)) &&
472
                console_table[currcons]->pgrp > 0)
473
                kill_pg(console_table[currcons]->pgrp, SIGWINCH, 1);
474
            console_table[currcons]->winsize = ws;
475
        }
476
 
477
   if (currcons == fg_console && vt_cons[fg_console]->vc_mode == KD_TEXT)
478
      update_screen(fg_console);
479
}
480
 
481
void vc_disallocate(unsigned int currcons)
482
{
483
        if (vc_cons_allocated(currcons)) {
484
            if (kmalloced)
485
              kfree_s(vc_scrbuf[currcons], screenbuf_size);
486
            if (currcons >= MIN_NR_CONSOLES)
487
              kfree_s(vc_cons[currcons].d, structsize);
488
            vc_cons[currcons].d = 0;
489
        }
490
}
491
 
492
 
493
#define set_kbd(x) set_vc_kbd_mode(kbd_table+currcons,x)
494
#define clr_kbd(x) clr_vc_kbd_mode(kbd_table+currcons,x)
495
#define is_kbd(x) vc_kbd_mode(kbd_table+currcons,x)
496
 
497
#define decarm          VC_REPEAT
498
#define decckm          VC_CKMODE
499
#define kbdapplic       VC_APPLIC
500
#define lnm             VC_CRLF
501
 
502
/*
503
 * this is what the terminal answers to a ESC-Z or csi0c query.
504
 */
505
#define VT100ID "\033[?1;2c"
506
#define VT102ID "\033[?6c"
507
 
508
static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
509
                                       8,12,10,14, 9,13,11,15 };
510
 
511
/*
512
 * gotoxy() must verify all boundaries, because the arguments
513
 * might also be negative. If the given position is out of
514
 * bounds, the cursor is placed at the nearest margin.
515
 */
516
static void gotoxy(int currcons, int new_x, int new_y)
517
{
518
        int min_y, max_y;
519
 
520
        if (new_x < 0)
521
                x = 0;
522
        else
523
                if (new_x >= cols)
524
                        x = cols - 1;
525
                else
526
                        x = new_x;
527
        if (decom) {
528
                min_y = top;
529
                max_y = bottom;
530
        } else {
531
                min_y = 0;
532
                max_y = rows;
533
        }
534
        if (new_y < min_y)
535
                y = min_y;
536
        else if (new_y >= max_y)
537
                y = max_y - 1;
538
        else
539
                y = new_y;
540
        pos = video_mem_start + y * cols + x;
541
        need_wrap = 0;
542
}
543
 
544
/* for absolute user moves, when decom is set */
545
static void gotoxay(int currcons, int new_x, int new_y)
546
{
547
        gotoxy(currcons, new_x, decom ? (top+new_y) : new_y);
548
}
549
 
550
static void hide_cursor(int currcons)
551
{
552
        sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
553
        return;
554
}
555
 
556
static void set_cursor(int currcons)
557
{
558
        if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
559
                return;
560
        if (deccm)
561
                sw->con_cursor(vc_cons[currcons].d,CM_DRAW);
562
        else
563
                hide_cursor(currcons);
564
        return;
565
}
566
 
567
void no_scroll(char *str, int *ints)
568
{
569
  /*
570
   * no_scroll currently does nothing on the m68k.
571
   */
572
}
573
 
574
/*
575
 * Arno:
576
 * Why do we need these? The keyboard code doesn't seem to do anything
577
 * with them either...
578
 */
579
void scrollfront(int l)
580
{
581
        return;
582
}
583
 
584
void scrollback(int l)
585
{
586
        return;
587
}
588
 
589
static void scrup(int currcons, unsigned int t, unsigned int b,
590
                  int nr)
591
{
592
        unsigned short *p;
593
        int i;
594
 
595
        if (b > rows || t >= b)
596
                return;
597
 
598
        memmove (video_mem_start + t * cols,
599
                 video_mem_start + (t + nr) * cols,
600
                 (b - t - nr) * cols * 2);
601
 
602
        p = video_mem_start + (b - nr) * cols;
603
        for (i = nr * cols; i > 0; i--)
604
          *p++ = video_erase_char;
605
 
606
        if (currcons != fg_console)
607
          return;
608
/*
609
 * Arno:
610
 * Scrolling has now been moved to amicon.c where it should have
611
 * been all along.
612
 */
613
        sw->con_scroll(vc_cons[currcons].d, t, b, SM_UP, nr);
614
 
615
        return;
616
 
617
}
618
 
619
static void scrdown(int currcons, unsigned int t, unsigned int b,
620
                    int nr)
621
{
622
        unsigned short *p;
623
        int i;
624
 
625
        if (b > rows || t >= b)
626
                return;
627
 
628
        memmove (video_mem_start + (t + nr) * cols,
629
                 video_mem_start + t * cols,
630
                 (b - t - nr) * cols * 2);
631
 
632
        p = video_mem_start + t * cols;
633
        for (i = nr * cols; i > 0; i--)
634
          *p++ = video_erase_char;
635
 
636
        if (currcons != fg_console)
637
          return;
638
/*
639
 * Arno:
640
 * Scrolling has now been moved to amicon.c where it should have
641
 * been all along.
642
 */
643
        sw->con_scroll(vc_cons[currcons].d, t, b, SM_DOWN, nr);
644
 
645
        return;
646
}
647
 
648
static void lf(int currcons)
649
{
650
        /* don't scroll if above bottom of scrolling region, or
651
         * if below scrolling region
652
         */
653
        if (y+1 == bottom)
654
                scrup(currcons,top,bottom, 1);
655
        else if (y < rows-1) {
656
                y++;
657
                pos += cols;
658
        }
659
        need_wrap = 0;
660
}
661
 
662
static void ri(int currcons)
663
{
664
        /* don't scroll if below top of scrolling region, or
665
         * if above scrolling region
666
         */
667
        if (y == top)
668
                scrdown(currcons,top,bottom, 1);
669
        else if (y > 0) {
670
                y--;
671
                pos -= cols;
672
        }
673
        need_wrap = 0;
674
}
675
 
676
static inline void cr(int currcons)
677
{
678
        pos -= x;
679
        need_wrap = x = 0;
680
}
681
 
682
static inline void bs(int currcons)
683
{
684
        if (x) {
685
                pos--;
686
                x--;
687
                need_wrap = 0;
688
        }
689
}
690
 
691
static inline void del(int currcons)
692
{
693
        /* ignored */
694
}
695
 
696
static void csi_J(int currcons, int vpar)
697
{
698
        unsigned long count;
699
        unsigned short *start;
700
 
701
        switch (vpar) {
702
                case 0:  /* erase from cursor to end of display */
703
                        count = (video_mem_start
704
                                 + cols * rows
705
                                 - pos);
706
                        start = pos;
707
                        if (currcons != fg_console)
708
                          break;
709
                        /* 680x0 do in two stages */
710
                        sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
711
                        sw->con_clear(vc_cons[currcons].d,y+1,0,rows-y-1, cols);
712
                        break;
713
                case 1: /* erase from start to cursor */
714
                        count = pos - video_mem_start + 1;
715
                        start = video_mem_start;
716
                        if (currcons != fg_console)
717
                          break;
718
                        /* 680x0 do in two stages */
719
                        sw->con_clear(vc_cons[currcons].d,0,0,y, cols);
720
                        sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
721
                        break;
722
                case 2: /* erase whole display */
723
                        count = cols * rows;
724
                        start = video_mem_start;
725
                        if (currcons != fg_console)
726
                          break;
727
                        sw->con_clear(vc_cons[currcons].d,0,0,rows, cols);
728
                        break;
729
                default:
730
                        return;
731
        }
732
        while (count-- > 0)
733
          *start++ = video_erase_char;
734
        need_wrap = 0;
735
}
736
 
737
static void csi_K(int currcons, int vpar)
738
{
739
        unsigned long count;
740
        unsigned short *start;
741
 
742
        switch (vpar) {
743
                case 0:  /* erase from cursor to end of line */
744
                        count = cols - x;
745
                        start = pos;
746
                        if (currcons != fg_console)
747
                          break;
748
                        sw->con_clear(vc_cons[currcons].d,y,x,1,cols-x);
749
                        break;
750
                case 1: /* erase from start of line to cursor */
751
                        start = pos - x;
752
                        count = x + 1;
753
                        if (currcons != fg_console)
754
                          break;
755
                        sw->con_clear(vc_cons[currcons].d,y,0,1,x + 1);
756
                        break;
757
                case 2: /* erase whole line */
758
                        start = pos - x;
759
                        count = cols;
760
                        if (currcons != fg_console)
761
                          break;
762
                        sw->con_clear(vc_cons[currcons].d,y,0,1,cols);
763
                        break;
764
                default:
765
                        return;
766
        }
767
        while (count-- > 0)
768
          *start++ = video_erase_char;
769
        need_wrap = 0;
770
}
771
 
772
static void csi_X(int currcons, int vpar) /* erase the following vpar positions */
773
{                                         /* not vt100? */
774
        unsigned long count;
775
        unsigned short * start;
776
 
777
        if (!vpar)
778
                vpar++;
779
 
780
        start=pos;
781
        count=(vpar > cols-x) ? (cols-x) : vpar;
782
 
783
        if (currcons == fg_console)
784
                sw->con_clear(vc_cons[currcons].d,y,x,1,count);
785
 
786
        while (count-- > 0)
787
                *start++ = video_erase_char;
788
        need_wrap = 0;
789
}
790
 
791
/*
792
 * Arno:
793
 * On 680x0 attributes are currently not used. This piece of code
794
 * seems hardware independent, but uses the EGA/VGA way of representing
795
 * attributes.
796
 * TODO: modify for 680x0 and add attribute processing to putc code.
797
 *
798
 * ++roman: I completely changed the attribute format for monochrome
799
 * mode (!can_do_color). The formerly used MDA (monochrome display
800
 * adapter) format didn't allow the combination of certain effects.
801
 * Now the attribute is just a bit vector:
802
 *  Bit 0..1: intensity (0..2)
803
 *  Bit 2   : underline
804
 *  Bit 3   : reverse
805
 *  Bit 7   : blink
806
 */
807
static void update_attr(int currcons)
808
{
809
        if (!can_do_color) {
810
                /* Special treatment for monochrome */
811
                attr = intensity |
812
                        (underline ? 4 : 0) |
813
                        ((reverse ^ decscnm) ? 8 : 0) |
814
                        (blink ? 0x80 : 0);
815
                video_erase_char = ' ' | ((reverse ^ decscnm) ? 0x800 : 0);
816
                return;
817
        }
818
 
819
        attr = color;
820
        if (underline)
821
                attr = (attr & 0xf0) | ulcolor;
822
        else if (intensity == 0)
823
                attr = (attr & 0xf0) | halfcolor;
824
        if (reverse ^ decscnm)
825
                attr = reverse_video_char(attr);
826
        if (blink)
827
                attr ^= 0x80;
828
        if (intensity == 2)
829
                attr ^= 0x08;
830
        if (decscnm)
831
                video_erase_char = (reverse_video_char(color) << 8) | ' ';
832
        else
833
                video_erase_char = (color << 8) | ' ';
834
}
835
 
836
static void default_attr(int currcons)
837
{
838
        intensity = 1;
839
        underline = 0;
840
        reverse = 0;
841
        blink = 0;
842
        color = def_color;
843
}
844
 
845
static void csi_m(int currcons)
846
{
847
        int i;
848
 
849
        for (i=0;i<=npar;i++)
850
                switch (par[i]) {
851
                        case 0:  /* all attributes off */
852
                                default_attr(currcons);
853
                                break;
854
                        case 1:
855
                                intensity = 2;
856
                                break;
857
                        case 2:
858
                                intensity = 0;
859
                                break;
860
                        case 4:
861
                                underline = 1;
862
                                break;
863
                        case 5:
864
                                blink = 1;
865
                                break;
866
                        case 7:
867
                                reverse = 1;
868
                                break;
869
                        case 10: /* ANSI X3.64-1979 (SCO-ish?)
870
                                  * Select primary font, don't display
871
                                  * control chars if defined, don't set
872
                                  * bit 8 on output.
873
                                  */
874
                                translate = set_translate(charset == 0
875
                                                ? G0_charset
876
                                                : G1_charset);
877
                                disp_ctrl = 0;
878
                                toggle_meta = 0;
879
                                break;
880
                        case 11: /* ANSI X3.64-1979 (SCO-ish?)
881
                                  * Select first alternate font, let's
882
                                  * chars < 32 be displayed as ROM chars.
883
                                  */
884
                                translate = set_translate(IBMPC_MAP);
885
                                disp_ctrl = 1;
886
                                toggle_meta = 0;
887
                                break;
888
                        case 12: /* ANSI X3.64-1979 (SCO-ish?)
889
                                  * Select second alternate font, toggle
890
                                  * high bit before displaying as ROM char.
891
                                  */
892
                                translate = set_translate(IBMPC_MAP);
893
                                disp_ctrl = 1;
894
                                toggle_meta = 1;
895
                                break;
896
                        case 21:
897
                        case 22:
898
                                intensity = 1;
899
                                break;
900
                        case 24:
901
                                underline = 0;
902
                                break;
903
                        case 25:
904
                                blink = 0;
905
                                break;
906
                        case 27:
907
                                reverse = 0;
908
                                break;
909
                        case 38: /* ANSI X3.64-1979 (SCO-ish?)
910
                                  * Enables underscore, white foreground
911
                                  * with white underscore (Linux - use
912
                                  * default foreground).
913
                                  */
914
                                color = (def_color & 0x0f) | background;
915
                                underline = 1;
916
                                break;
917
                        case 39: /* ANSI X3.64-1979 (SCO-ish?)
918
                                  * Disable underline option.
919
                                  * Reset colour to default? It did this
920
                                  * before...
921
                                  */
922
                                color = (def_color & 0x0f) | background;
923
                                underline = 0;
924
                                break;
925
                        case 49:
926
                                color = (def_color & 0xf0) | foreground;
927
                                break;
928
                        default:
929
                                if (par[i] >= 30 && par[i] <= 37)
930
                                        color = color_table[par[i]-30]
931
                                                | background;
932
                                else if (par[i] >= 40 && par[i] <= 47)
933
                                        color = (color_table[par[i]-40]<<4)
934
                                                | foreground;
935
                                break;
936
                }
937
        update_attr(currcons);
938
}
939
 
940
static void respond_string(const char * p, struct tty_struct * tty)
941
{
942
        while (*p) {
943
                tty_insert_flip_char(tty, *p, 0);
944
                p++;
945
        }
946
        tty_schedule_flip(tty);
947
}
948
 
949
static void cursor_report(int currcons, struct tty_struct * tty)
950
{
951
        char buf[40];
952
 
953
        sprintf(buf, "\033[%ld;%ldR", y + (decom ? top+1 : 1), x+1);
954
        respond_string(buf, tty);
955
}
956
 
957
static inline void status_report(struct tty_struct * tty)
958
{
959
        respond_string("\033[0n", tty); /* Terminal ok */
960
}
961
 
962
static inline void respond_ID(struct tty_struct * tty)
963
{
964
        respond_string(VT102ID, tty);
965
}
966
 
967
void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry)
968
{
969
        char buf[8];
970
 
971
        sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
972
                (char)('!' + mry));
973
        respond_string(buf, tty);
974
}
975
 
976
/* invoked via ioctl(TIOCLINUX) */
977
int mouse_reporting(void)
978
{
979
        int currcons = fg_console;
980
 
981
        return report_mouse;
982
}
983
 
984
static inline unsigned short *screenpos(int currcons, int offset, int viewed)
985
{
986
        unsigned short *p = (unsigned short *)(origin + offset);
987
#if 0
988
        if (viewed && currcons == fg_console)
989
                p -= (__real_origin - __origin);
990
#endif
991
        return p;
992
}
993
 
994
/* Note: inverting the screen twice should revert to the original state */
995
void invert_screen(int currcons, int offset, int count, int viewed)
996
{
997
        unsigned short *p;
998
        unsigned short xx, yy, oldattr;
999
 
1000
        count /= 2;
1001
        p = screenpos(currcons, offset, viewed);
1002
        xx = (offset >> 1) % cols;
1003
        yy = (offset >> 1) / cols;
1004
        oldattr = attr;
1005
        if (can_do_color)
1006
                while (count--) {
1007
                        unsigned short old = scr_readw(p);
1008
                        unsigned short new = reverse_video_short(old);
1009
                        scr_writew(new, p);
1010
                        p++;
1011
                        if (currcons != fg_console)
1012
                                continue;
1013
                        attr = new >> 8;
1014
                        sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
1015
                        if (++xx == cols)
1016
                                xx = 0, ++yy;
1017
                }
1018
        else
1019
                while (count--) {
1020
                        unsigned short old = scr_readw(p);
1021
                        unsigned short new = old ^ 0x800;
1022
                        scr_writew(new, p);
1023
                        p++;
1024
                        if (currcons != fg_console)
1025
                                continue;
1026
                        attr = new >> 8;
1027
                        sw->con_putc(vc_cons[currcons].d, new & 0xff, yy, xx);
1028
                        if (++xx == cols)
1029
                                xx = 0, ++yy;
1030
                }
1031
        attr = oldattr;
1032
}
1033
 
1034
/* used by selection: complement pointer position */
1035
void complement_pos(int currcons, int offset)
1036
{
1037
        static unsigned short *p = NULL;
1038
        static unsigned short old = 0;
1039
        static unsigned short oldx = 0, oldy = 0;
1040
        unsigned short new, oldattr;
1041
 
1042
        oldattr = attr;
1043
        if (p) {
1044
                scr_writew(old, p);
1045
                if (currcons == fg_console) {
1046
                        attr = old >> 8;
1047
                        sw->con_putc(vc_cons[currcons].d, old & 0xff, oldy, oldx);
1048
                        attr = oldattr;
1049
                }
1050
        }
1051
        if (offset == -1)
1052
                p = NULL;
1053
        else {
1054
                p = screenpos(currcons, offset, 1);
1055
                old = scr_readw(p);
1056
                oldx = (offset >> 1) % cols;
1057
                oldy = (offset >> 1) / cols;
1058
                if (can_do_color)
1059
                        new = old ^ 0x7700;
1060
                else
1061
                        new = old ^ 0x800;
1062
                scr_writew(new, p);
1063
                if (currcons == fg_console) {
1064
                        attr = new >> 8;
1065
                        sw->con_putc(vc_cons[currcons].d, new & 0xff, oldy, oldx);
1066
                        attr = oldattr;
1067
                }
1068
        }
1069
}
1070
 
1071
/* used by selection */
1072
unsigned short screen_word(int currcons, int offset, int viewed)
1073
{
1074
        return scr_readw(screenpos(currcons, offset, viewed));
1075
}
1076
 
1077
/* used by selection - convert a screen word to a glyph number */
1078
int scrw2glyph(unsigned short scr_word)
1079
{
1080
        return ( video_mode_512ch )
1081
                ? ((scr_word & 0x0800) >> 3) + (scr_word & 0x00ff)
1082
                : scr_word & 0x00ff;
1083
}
1084
 
1085
/* used by vcs - note the word offset */
1086
unsigned short *screen_pos(int currcons, int w_offset, int viewed)
1087
{
1088
        return screenpos(currcons, 2 * w_offset, viewed);
1089
}
1090
 
1091
void getconsxy(int currcons, char *p)
1092
{
1093
        p[0] = x;
1094
        p[1] = y;
1095
}
1096
 
1097
void putconsxy(int currcons, char *p)
1098
{
1099
        gotoxy(currcons, p[0], p[1]);
1100
        set_cursor(currcons);
1101
}
1102
 
1103
static void set_mode(int currcons, int on_off)
1104
{
1105
        int i;
1106
 
1107
        for (i=0; i<=npar; i++)
1108
                if (ques) switch(par[i]) {      /* DEC private modes set/reset */
1109
                        case 1:                 /* Cursor keys send ^[Ox/^[[x */
1110
                                if (on_off)
1111
                                        set_kbd(decckm);
1112
                                else
1113
                                        clr_kbd(decckm);
1114
                                break;
1115
                        case 3: /* 80/132 mode switch unimplemented */
1116
                                deccolm = on_off;
1117
#if 0
1118
                                (void) vc_resize(rows, deccolm ? 132 : 80);
1119
                                /* this alone does not suffice; some user mode
1120
                                   utility has to change the hardware regs */
1121
#endif
1122
                                break;
1123
                        case 5:                 /* Inverted screen on/off */
1124
                                if (decscnm != on_off) {
1125
                                        decscnm = on_off;
1126
                                        invert_screen(currcons, 0, screenbuf_size, 0);
1127
                                        update_attr(currcons);
1128
                                }
1129
                                break;
1130
                        case 6:                 /* Origin relative/absolute */
1131
                                decom = on_off;
1132
                                gotoxay(currcons,0,0);
1133
                                break;
1134
                        case 7:                 /* Autowrap on/off */
1135
                                decawm = on_off;
1136
                                break;
1137
                        case 8:                 /* Autorepeat on/off */
1138
                                if (on_off)
1139
                                        set_kbd(decarm);
1140
                                else
1141
                                        clr_kbd(decarm);
1142
                                break;
1143
                        case 9:
1144
                                report_mouse = on_off ? 1 : 0;
1145
                                break;
1146
                        case 25:                /* Cursor on/off */
1147
                                deccm = on_off;
1148
                                set_cursor(currcons);
1149
                                break;
1150
                        case 1000:
1151
                                report_mouse = on_off ? 2 : 0;
1152
                                break;
1153
                } else switch(par[i]) {         /* ANSI modes set/reset */
1154
                        case 3:                 /* Monitor (display ctrls) */
1155
                                disp_ctrl = on_off;
1156
                                break;
1157
                        case 4:                 /* Insert Mode on/off */
1158
                                decim = on_off;
1159
                                break;
1160
                        case 20:                /* Lf, Enter == CrLf/Lf */
1161
                                if (on_off)
1162
                                        set_kbd(lnm);
1163
                                else
1164
                                        clr_kbd(lnm);
1165
                                break;
1166
                }
1167
}
1168
 
1169
static void setterm_command(int currcons)
1170
{
1171
        switch(par[0]) {
1172
                case 1: /* set color for underline mode */
1173
                        if (can_do_color && par[1] < 16) {
1174
                                ulcolor = color_table[par[1]];
1175
                                if (underline)
1176
                                        update_attr(currcons);
1177
                        }
1178
                        break;
1179
                case 2: /* set color for half intensity mode */
1180
                        if (can_do_color && par[1] < 16) {
1181
                                halfcolor = color_table[par[1]];
1182
                                if (intensity == 0)
1183
                                        update_attr(currcons);
1184
                        }
1185
                        break;
1186
                case 8: /* store colors as defaults */
1187
                        def_color = attr;
1188
                        default_attr(currcons);
1189
                        update_attr(currcons);
1190
                        break;
1191
                case 9: /* set blanking interval */
1192
                        blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
1193
                        poke_blanked_console();
1194
                        break;
1195
                case 10: /* set bell frequency in Hz */
1196
                        if (npar >= 1)
1197
                                bell_pitch = par[1];
1198
                        else
1199
                                bell_pitch = DEFAULT_BELL_PITCH;
1200
                        break;
1201
                case 11: /* set bell duration in msec */
1202
                        if (npar >= 1)
1203
                                bell_duration = (par[1] < 2000) ?
1204
                                        par[1]*HZ/1000 : 0;
1205
                        else
1206
                                bell_duration = DEFAULT_BELL_DURATION;
1207
                        break;
1208
                case 12: /* bring specified console to the front */
1209
                        if (par[1] >= 1 && vc_cons_allocated(par[1]-1))
1210
                                update_screen(par[1]-1);
1211
                        break;
1212
                case 13: /* unblank the screen */
1213
                        unblank_screen();
1214
                        break;
1215
                case 14: /* set vesa powerdown interval */
1216
                        vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
1217
                        break;
1218
        }
1219
}
1220
 
1221
static void insert_char(int currcons)
1222
{
1223
        int i;
1224
        unsigned short *p = pos;
1225
 
1226
        for (i = cols - x - 2; i >= 0; i--)
1227
          p[i + 1] = p[i];
1228
        *pos = video_erase_char;
1229
        need_wrap = 0;
1230
 
1231
        if (currcons != fg_console)
1232
          return;
1233
 
1234
        /* Arno:
1235
         * Move the remainder of the line (-1 character) one spot to the right
1236
         */
1237
        sw->con_bmove(vc_cons[currcons].d,y,x,y,x+1,1,(cols-x-1));
1238
        /*
1239
         * Print the erase char on the current position
1240
         */
1241
        sw->con_putc(vc_cons[currcons].d,(video_erase_char & 0x00ff),y,x);
1242
}
1243
 
1244
static void csi_at(int currcons, unsigned int nr)
1245
{
1246
        int i;
1247
        unsigned short *p;
1248
 
1249
        if (nr > cols - x)
1250
                nr = cols - x;
1251
        else if (!nr)
1252
                nr = 1;
1253
 
1254
        p = pos + cols - x - nr;
1255
        while (--p >= pos)
1256
          p[nr] = *p;
1257
        for (i = 0; i < nr; i++)
1258
          *++p = video_erase_char;
1259
        need_wrap = 0;
1260
 
1261
        if (currcons != fg_console)
1262
          return;
1263
 
1264
        sw->con_bmove (vc_cons[currcons].d, y, x, y, x + nr,
1265
                       1, cols - x - nr);
1266
        while (nr--)
1267
          sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
1268
                        y, x + nr);
1269
}
1270
 
1271
static void csi_L(int currcons, unsigned int nr)
1272
{
1273
        if (nr > rows)
1274
                nr = rows;
1275
        else if (!nr)
1276
                nr = 1;
1277
        scrdown (currcons, y, bottom, nr);
1278
        need_wrap = 0;
1279
}
1280
 
1281
static void csi_P(int currcons, unsigned int nr)
1282
{
1283
        int i;
1284
        unsigned short *p, *end;
1285
 
1286
        if (nr > cols - x)
1287
                nr = cols - x;
1288
        else if (!nr)
1289
                nr = 1;
1290
 
1291
        p = pos;
1292
        end = pos + cols - x - nr;
1293
        while (p < end)
1294
          *p = p[nr], p++;
1295
        for (i = 0; i < nr; i++)
1296
          *p++ = video_erase_char;
1297
        need_wrap = 0;
1298
 
1299
        if (currcons != fg_console)
1300
          return;
1301
 
1302
        sw->con_bmove (vc_cons[currcons].d, y, x + nr, y, x,
1303
                       1, cols - x - nr);
1304
 
1305
        while (nr--)
1306
          sw->con_putc (vc_cons[currcons].d, video_erase_char & 0x00ff,
1307
                        y, cols - 1 - nr);
1308
}
1309
 
1310
static void csi_M(int currcons, unsigned int nr)
1311
{
1312
        if (nr > rows)
1313
                nr = rows;
1314
        else if (!nr)
1315
                nr=1;
1316
        scrup (currcons, y, bottom, nr);
1317
        need_wrap = 0;
1318
}
1319
 
1320
static void save_cur(int currcons)
1321
{
1322
        saved_x         = x;
1323
        saved_y         = y;
1324
        s_intensity     = intensity;
1325
        s_underline     = underline;
1326
        s_blink         = blink;
1327
        s_reverse       = reverse;
1328
        s_charset       = charset;
1329
        s_color         = color;
1330
        saved_G0        = G0_charset;
1331
        saved_G1        = G1_charset;
1332
}
1333
 
1334
static void restore_cur(int currcons)
1335
{
1336
        gotoxy(currcons,saved_x,saved_y);
1337
        intensity       = s_intensity;
1338
        underline       = s_underline;
1339
        blink           = s_blink;
1340
        reverse         = s_reverse;
1341
        charset         = s_charset;
1342
        color           = s_color;
1343
        G0_charset      = saved_G0;
1344
        G1_charset      = saved_G1;
1345
        translate       = set_translate(charset ? G1_charset : G0_charset);
1346
        update_attr(currcons);
1347
        need_wrap = 0;
1348
}
1349
 
1350
enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
1351
        EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
1352
        ESpalette };
1353
 
1354
static void reset_terminal(int currcons, int do_clear)
1355
{
1356
        top             = 0;
1357
        bottom          = rows;
1358
        vc_state        = ESnormal;
1359
        ques            = 0;
1360
        translate       = set_translate(LAT1_MAP);
1361
        G0_charset      = LAT1_MAP;
1362
        G1_charset      = GRAF_MAP;
1363
        charset         = 0;
1364
        need_wrap       = 0;
1365
        report_mouse    = 0;
1366
        utf             = 0;
1367
        utf_count       = 0;
1368
 
1369
        disp_ctrl       = 0;
1370
        toggle_meta     = 0;
1371
 
1372
        decscnm         = 0;
1373
        decom           = 0;
1374
        decawm          = 1;
1375
        deccm           = 1;
1376
        decim           = 0;
1377
 
1378
        set_kbd(decarm);
1379
        clr_kbd(decckm);
1380
        clr_kbd(kbdapplic);
1381
        clr_kbd(lnm);
1382
        kbd_table[currcons].lockstate = 0;
1383
        kbd_table[currcons].slockstate = 0;
1384
        kbd_table[currcons].ledmode = LED_SHOW_FLAGS;
1385
        kbd_table[currcons].ledflagstate = kbd_table[currcons].default_ledflagstate;
1386
        set_leds();
1387
 
1388
        default_attr(currcons);
1389
        update_attr(currcons);
1390
 
1391
        tab_stop[0]      = 0x01010100;
1392
        tab_stop[1]     =
1393
        tab_stop[2]     =
1394
        tab_stop[3]     =
1395
        tab_stop[4]     = 0x01010101;
1396
 
1397
        bell_pitch = DEFAULT_BELL_PITCH;
1398
        bell_duration = DEFAULT_BELL_DURATION;
1399
 
1400
        gotoxy(currcons,0,0);
1401
        save_cur(currcons);
1402
        if (do_clear)
1403
            csi_J(currcons,2);
1404
}
1405
 
1406
/*
1407
 * Turn the Scroll-Lock LED on when the tty is stopped
1408
 */
1409
static void con_stop(struct tty_struct *tty)
1410
{
1411
        int console_num;
1412
        if (!tty)
1413
                return;
1414
        console_num = MINOR(tty->device) - (tty->driver.minor_start);
1415
        if (!vc_cons_allocated(console_num))
1416
                return;
1417
        set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1418
        set_leds();
1419
}
1420
 
1421
/*
1422
 * Turn the Scroll-Lock LED off when the console is started
1423
 */
1424
static void con_start(struct tty_struct *tty)
1425
{
1426
        int console_num;
1427
        if (!tty)
1428
                return;
1429
        console_num = MINOR(tty->device) - (tty->driver.minor_start);
1430
        if (!vc_cons_allocated(console_num))
1431
                return;
1432
        clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
1433
        set_leds();
1434
}
1435
 
1436
static int con_write(struct tty_struct * tty, int from_user,
1437
                     const unsigned char *buf, int count)
1438
{
1439
        int c, tc, ok, n = 0;
1440
        unsigned int currcons;
1441
        struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
1442
 
1443
        currcons = vt->vc_num;
1444
        if (!vc_cons_allocated(currcons)) {
1445
                /* could this happen? */
1446
                static int error = 0;
1447
                if (!error) {
1448
                        error = 1;
1449
                        printk("con_write: tty %d not allocated\n", currcons+1);
1450
                }
1451
                return 0;
1452
        }
1453
 
1454
        /* undraw cursor first */
1455
        if (currcons == fg_console)
1456
                hide_cursor(currcons);
1457
 
1458
        /* clear the selection */
1459
        if (currcons == sel_cons)
1460
                clear_selection();
1461
 
1462
        disable_bh(CONSOLE_BH);
1463
        while (count) {
1464
                enable_bh(CONSOLE_BH);
1465
                c = from_user ? get_user(buf) : *buf;
1466
                buf++; n++; count--;
1467
                disable_bh(CONSOLE_BH);
1468
 
1469
                if (utf) {
1470
                    /* Combine UTF-8 into Unicode */
1471
                    /* Incomplete characters silently ignored */
1472
                    if(c > 0x7f) {
1473
                        if (utf_count > 0 && (c & 0xc0) == 0x80) {
1474
                                utf_char = (utf_char << 6) | (c & 0x3f);
1475
                                utf_count--;
1476
                                if (utf_count == 0)
1477
                                    tc = c = utf_char;
1478
                                else continue;
1479
                        } else {
1480
                                if ((c & 0xe0) == 0xc0) {
1481
                                    utf_count = 1;
1482
                                    utf_char = (c & 0x1f);
1483
                                } else if ((c & 0xf0) == 0xe0) {
1484
                                    utf_count = 2;
1485
                                    utf_char = (c & 0x0f);
1486
                                } else if ((c & 0xf8) == 0xf0) {
1487
                                    utf_count = 3;
1488
                                    utf_char = (c & 0x07);
1489
                                } else if ((c & 0xfc) == 0xf8) {
1490
                                    utf_count = 4;
1491
                                    utf_char = (c & 0x03);
1492
                                } else if ((c & 0xfe) == 0xfc) {
1493
                                    utf_count = 5;
1494
                                    utf_char = (c & 0x01);
1495
                                } else
1496
                                    utf_count = 0;
1497
                                continue;
1498
                        }
1499
                    } else {
1500
                        tc = c;
1501
                        utf_count = 0;
1502
                    }
1503
                } else {        /* no utf */
1504
                    tc = translate[toggle_meta ? (c|0x80) : c];
1505
                }
1506
 
1507
                /* If the original code was a control character we
1508
                 * only allow a glyph to be displayed if the code is
1509
                 * not normally used (such as for cursor movement) or
1510
                 * if the disp_ctrl mode has been explicitly enabled.
1511
                 * Certain characters (as given by the CTRL_ALWAYS
1512
                 * bitmap) are always displayed as control characters,
1513
                 * as the console would be pretty useless without
1514
                 * them; to display an arbitrary font position use the
1515
                 * direct-to-font zone in UTF-8 mode.
1516
                 */
1517
                ok = tc && (c >= 32 ||
1518
                            (!utf && !(((disp_ctrl ? CTRL_ALWAYS
1519
                                         : CTRL_ACTION) >> c) & 1)))
1520
                        && (c != 127 || disp_ctrl);
1521
 
1522
                if (vc_state == ESnormal && ok) {
1523
                        /* Now try to find out how to display it */
1524
                        tc = conv_uni_to_pc(tc);
1525
                        if ( tc == -4 ) {
1526
                                /* If we got -4 (not found) then see if we have
1527
                                   defined a replacement character (U+FFFD) */
1528
                                tc = conv_uni_to_pc(0xfffd);
1529
                        } else if ( tc == -3 ) {
1530
                                /* Bad hash table -- hope for the best */
1531
                                tc = c;
1532
                        }
1533
                        if (tc & ~console_charmask)
1534
                                continue; /* Conversion failed */
1535
 
1536
                        if (need_wrap) {
1537
                                cr(currcons);
1538
                                lf(currcons);
1539
                        }
1540
 
1541
#if 1 /* XXX */
1542
                        /* DPC: 1994-04-12
1543
                         *   Speed up overstrike mode, using new putcs.
1544
                         *
1545
                         * P.S. I hate 8 spaces per tab! Use Emacs!
1546
                         */
1547
 
1548
                        /* Only use this for the foreground console,
1549
                           where we really draw the chars */
1550
 
1551
                        if (count > 2 &&
1552
                            !decim && !utf && currcons == fg_console) {
1553
                                static char putcs_buf[256];
1554
                                char   *p     = putcs_buf;
1555
                                int putcs_count  = 1;
1556
                                ushort nextx  = x + 1;
1557
 
1558
                                *p++ = tc;
1559
                                *pos++ = tc | (attr << 8);
1560
 
1561
                                if (nextx == cols) {
1562
                                        sw->con_putc(vc_cons[currcons].d,
1563
                                                     *putcs_buf, y, x);
1564
                                        pos--;
1565
                                        need_wrap = decawm;
1566
                                        continue;
1567
                                }
1568
 
1569
                                /* TAB TAB TAB - Arghh!!!! */
1570
 
1571
                                while (count)
1572
                                {
1573
                                        enable_bh(CONSOLE_BH);
1574
                                        c = from_user ? get_user(buf) : *buf;
1575
                                        disable_bh(CONSOLE_BH);
1576
                                        tc = translate[toggle_meta ? (c|0x80) : c];
1577
                                        if (!tc ||
1578
                                            !(c >= 32
1579
                                              || !(((disp_ctrl ? CTRL_ALWAYS
1580
                                                   : CTRL_ACTION) >> c) & 1)))
1581
                                          break;
1582
                                        tc = conv_uni_to_pc(tc);
1583
                                        if (tc == -4)
1584
                                          tc = conv_uni_to_pc(0xfffd);
1585
                                        else if (tc == -3)
1586
                                          tc = c;
1587
 
1588
                                        buf++; n++; count--;
1589
                                        if (tc & ~console_charmask)
1590
                                          continue; /* Conversion failed */
1591
 
1592
                                        *p++ = tc;
1593
                                        *pos++ = tc | (attr << 8);
1594
                                        ++putcs_count;
1595
                                        ++nextx;
1596
                                        if (nextx == cols ||
1597
                                            putcs_count == sizeof (putcs_buf))
1598
                                                break;
1599
                                }
1600
 
1601
                                sw->con_putcs(vc_cons[currcons].d,
1602
                                              putcs_buf, putcs_count, y, x);
1603
                                if (nextx == cols) {
1604
                                        pos--;
1605
                                        x         = cols-1;
1606
                                        need_wrap = decawm;
1607
                                } else
1608
                                        x += putcs_count;
1609
                                continue;
1610
                        }
1611
 
1612
                        /* DPC: End of putcs support */
1613
#endif
1614
 
1615
                        if (decim)
1616
                                insert_char(currcons);
1617
                        *pos = (attr << 8) + tc;
1618
                        if (currcons == fg_console)
1619
                                sw->con_putc(vc_cons[currcons].d,tc,y,x);
1620
                        if (x == cols - 1)
1621
                                need_wrap = decawm;
1622
                        else {
1623
                                pos++;
1624
                                x++;
1625
                        }
1626
                        continue;
1627
                }
1628
 
1629
                /*
1630
                 *  Control characters can be used in the _middle_
1631
                 *  of an escape sequence.
1632
                 */
1633
                switch (c) {
1634
                    case 7:
1635
                        if (bell_duration)
1636
                            kd_mksound(bell_pitch, bell_duration);
1637
                        continue;
1638
                    case 8:
1639
                        bs(currcons);
1640
                        continue;
1641
                    case 9:
1642
                        pos -= x;
1643
                        while (x < cols - 1) {
1644
                                x++;
1645
                                if (tab_stop[x >> 5] & (1 << (x & 31)))
1646
                                        break;
1647
                        }
1648
                        pos += x;
1649
                        continue;
1650
                    case 10: case 11: case 12:
1651
                        lf(currcons);
1652
                        if (!is_kbd(lnm))
1653
                                continue;
1654
                    case 13:
1655
                        cr(currcons);
1656
                        continue;
1657
                        case 14:
1658
                        charset = 1;
1659
                        translate = set_translate(G1_charset);
1660
                        disp_ctrl = 1;
1661
                        continue;
1662
                    case 15:
1663
                        charset = 0;
1664
                        translate = set_translate(G0_charset);
1665
                        disp_ctrl = 0;
1666
                        continue;
1667
                    case 24: case 26:
1668
                        vc_state = ESnormal;
1669
                        continue;
1670
                    case 27:
1671
                        vc_state = ESesc;
1672
                        continue;
1673
                    case 127:
1674
                        del(currcons);
1675
                        continue;
1676
                    case 128+27:
1677
                        vc_state = ESsquare;
1678
                        continue;
1679
                }
1680
                switch(vc_state) {
1681
                    case ESesc:
1682
                        vc_state = ESnormal;
1683
                        switch (c) {
1684
                            case '[':
1685
                                vc_state = ESsquare;
1686
                                continue;
1687
                            case ']':
1688
                                vc_state = ESnonstd;
1689
                                continue;
1690
                            case '%':
1691
                                vc_state = ESpercent;
1692
                                continue;
1693
                            case 'E':
1694
                                cr(currcons);
1695
                                lf(currcons);
1696
                                continue;
1697
                            case 'M':
1698
                                ri(currcons);
1699
                                continue;
1700
                            case 'D':
1701
                                lf(currcons);
1702
                                continue;
1703
                            case 'H':
1704
                                tab_stop[x >> 5] |= (1 << (x & 31));
1705
                                continue;
1706
                            case 'Z':
1707
                                respond_ID(tty);
1708
                                continue;
1709
                            case '7':
1710
                                save_cur(currcons);
1711
                                continue;
1712
                            case '8':
1713
                                restore_cur(currcons);
1714
                                continue;
1715
                            case '(':
1716
                                vc_state = ESsetG0;
1717
                                continue;
1718
                            case ')':
1719
                                vc_state = ESsetG1;
1720
                                continue;
1721
                            case '#':
1722
                                vc_state = EShash;
1723
                                continue;
1724
                            case 'c':
1725
                                reset_terminal(currcons,1);
1726
                                continue;
1727
                            case '>':  /* Numeric keypad */
1728
                                clr_kbd(kbdapplic);
1729
                                continue;
1730
                            case '=':  /* Appl. keypad */
1731
                                set_kbd(kbdapplic);
1732
                                continue;
1733
                        }
1734
                        continue;
1735
                    case ESnonstd:
1736
                        if (c=='P') {   /* palette escape sequence */
1737
                            for (npar=0; npar<NPAR; npar++)
1738
                                par[npar] = 0 ;
1739
                            npar = 0 ;
1740
                            vc_state = ESpalette;
1741
                            continue;
1742
                        } else if (c=='R') {   /* reset palette */
1743
#if 0
1744
                            reset_palette (currcons);
1745
#endif
1746
                            vc_state = ESnormal;
1747
                        } else
1748
                            vc_state = ESnormal;
1749
                        continue;
1750
                case ESpalette:
1751
                        if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
1752
                            par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
1753
                            if (npar==7) {
1754
#if 0
1755
                                int i = par[0]*3, j = 1;
1756
                                palette[i] = 16*par[j++];
1757
                                palette[i++] += par[j++];
1758
                                palette[i] = 16*par[j++];
1759
                                palette[i++] += par[j++];
1760
                                palette[i] = 16*par[j++];
1761
                                palette[i] += par[j];
1762
                                set_palette() ;
1763
#endif
1764
                                vc_state = ESnormal;
1765
                            }
1766
                        } else
1767
                            vc_state = ESnormal;
1768
                        continue;
1769
                    case ESsquare:
1770
                        for(npar = 0 ; npar < NPAR ; npar++)
1771
                                par[npar] = 0;
1772
                        npar = 0;
1773
                        vc_state = ESgetpars;
1774
                        if (c == '[') { /* Function key */
1775
                                vc_state=ESfunckey;
1776
                                continue;
1777
                        }
1778
                        ques = (c=='?');
1779
                        if (ques)
1780
                                continue;
1781
                    case ESgetpars:
1782
                        if (c==';' && npar<NPAR-1) {
1783
                                npar++;
1784
                                continue;
1785
                        } else if (c>='0' && c<='9') {
1786
                                par[npar] *= 10;
1787
                                par[npar] += c-'0';
1788
                                continue;
1789
                        } else vc_state=ESgotpars;
1790
                    case ESgotpars:
1791
                        vc_state = ESnormal;
1792
                        switch(c) {
1793
                            case 'h':
1794
                                set_mode(currcons,1);
1795
                                continue;
1796
                            case 'l':
1797
                                set_mode(currcons,0);
1798
                                continue;
1799
                            case 'n':
1800
                                if (!ques)
1801
                                        if (par[0] == 5)
1802
                                                status_report(tty);
1803
                                        else if (par[0] == 6)
1804
                                                cursor_report(currcons,tty);
1805
                                continue;
1806
                        }
1807
                        if (ques) {
1808
                                ques = 0;
1809
                                continue;
1810
                        }
1811
                        switch(c) {
1812
                            case 'G': case '`':
1813
                                if (par[0]) par[0]--;
1814
                                gotoxy(currcons,par[0],y);
1815
                                continue;
1816
                            case 'A':
1817
                                if (!par[0]) par[0]++;
1818
                                gotoxy(currcons,x,y-par[0]);
1819
                                continue;
1820
                            case 'B': case 'e':
1821
                                if (!par[0]) par[0]++;
1822
                                gotoxy(currcons,x,y+par[0]);
1823
                                continue;
1824
                            case 'C': case 'a':
1825
                                if (!par[0]) par[0]++;
1826
                                gotoxy(currcons,x+par[0],y);
1827
                                continue;
1828
                            case 'D':
1829
                                if (!par[0]) par[0]++;
1830
                                gotoxy(currcons,x-par[0],y);
1831
                                continue;
1832
                            case 'E':
1833
                                if (!par[0]) par[0]++;
1834
                                gotoxy(currcons,0,y+par[0]);
1835
                                continue;
1836
                            case 'F':
1837
                                if (!par[0]) par[0]++;
1838
                                gotoxy(currcons,0,y-par[0]);
1839
                                continue;
1840
                            case 'd':
1841
                                if (par[0]) par[0]--;
1842
                                gotoxay(currcons,x,par[0]);
1843
                                continue;
1844
                            case 'H': case 'f':
1845
                                if (par[0]) par[0]--;
1846
                                if (par[1]) par[1]--;
1847
                                gotoxay(currcons,par[1],par[0]);
1848
                                continue;
1849
                            case 'J':
1850
                                csi_J(currcons,par[0]);
1851
                                continue;
1852
                            case 'K':
1853
                                csi_K(currcons,par[0]);
1854
                                continue;
1855
                            case 'L':
1856
                                csi_L(currcons,par[0]);
1857
                                continue;
1858
                            case 'M':
1859
                                csi_M(currcons,par[0]);
1860
                                continue;
1861
                            case 'P':
1862
                                csi_P(currcons,par[0]);
1863
                                continue;
1864
                            case 'c':
1865
                                if (!par[0])
1866
                                        respond_ID(tty);
1867
                                continue;
1868
                            case 'g':
1869
                                if (!par[0])
1870
                                        tab_stop[x >> 5] &= ~(1 << (x & 31));
1871
                                else if (par[0] == 3) {
1872
                                        tab_stop[0] =
1873
                                                tab_stop[1] =
1874
                                                        tab_stop[2] =
1875
                                                                tab_stop[3] =
1876
                                                                        tab_stop[4] = 0;
1877
                                }
1878
                                continue;
1879
                            case 'm':
1880
                                csi_m(currcons);
1881
                                continue;
1882
                            case 'q': /* DECLL - but only 3 leds */
1883
                                /* map 0,1,2,3 to 0,1,2,4 */
1884
                                if (par[0] < 4)
1885
                                        setledstate(kbd_table + currcons,
1886
                                                    (par[0] < 3) ? par[0] : 4);
1887
                                continue;
1888
                            case 'r':
1889
                                if (!par[0])
1890
                                        par[0]++;
1891
                                if (!par[1])
1892
                                        par[1] = rows;
1893
                                /* Minimum allowed region is 2 lines */
1894
                                if (par[0] < par[1] &&
1895
                                    par[1] <= rows) {
1896
                                        top=par[0]-1;
1897
                                        bottom=par[1];
1898
                                        gotoxay(currcons,0,0);
1899
                                }
1900
                                continue;
1901
                            case 's':
1902
                                save_cur(currcons);
1903
                                continue;
1904
                            case 'u':
1905
                                restore_cur(currcons);
1906
                                continue;
1907
                            case 'X':
1908
                                csi_X(currcons, par[0]);
1909
                                continue;
1910
                            case '@':
1911
                                csi_at(currcons,par[0]);
1912
                                continue;
1913
                            case ']': /* setterm functions */
1914
                                setterm_command(currcons);
1915
                                continue;
1916
                        }
1917
                        continue;
1918
                    case ESpercent:
1919
                        vc_state = ESnormal;
1920
                        switch (c) {
1921
                            case '@':  /* defined in ISO 2022 */
1922
                                utf = 0;
1923
                                continue;
1924
                            case 'G':  /* prelim official escape code */
1925
                            case '8':  /* retained for compatibility */
1926
                                utf = 1;
1927
                                continue;
1928
                        }
1929
                        continue;
1930
                    case ESfunckey:
1931
                        vc_state = ESnormal;
1932
                        continue;
1933
                    case EShash:
1934
                        vc_state = ESnormal;
1935
                        if (c == '8') {
1936
                                /* DEC screen alignment test. kludge :-) */
1937
                                video_erase_char =
1938
                                        (video_erase_char & 0xff00) | 'E';
1939
                                /* Arno:
1940
                                 * Doesn't work, because csi_J(c,2)
1941
                                 * calls con_clear and doesn't print
1942
                                 * the erase char..
1943
                                 */
1944
                                csi_J(currcons, 2);
1945
                                video_erase_char =
1946
                                        (video_erase_char & 0xff00) | ' ';
1947
                        }
1948
                        continue;
1949
                    case ESsetG0:
1950
                        if (c == '0')
1951
                                G0_charset = GRAF_MAP;
1952
                        else if (c == 'B')
1953
                                G0_charset = LAT1_MAP;
1954
                        else if (c == 'U')
1955
                                G0_charset = IBMPC_MAP;
1956
                        else if (c == 'K')
1957
                                G0_charset = USER_MAP;
1958
                        if (charset == 0)
1959
                                translate = set_translate(G0_charset);
1960
                        vc_state = ESnormal;
1961
                        continue;
1962
                    case ESsetG1:
1963
                        if (c == '0')
1964
                                G1_charset = GRAF_MAP;
1965
                        else if (c == 'B')
1966
                                G1_charset = LAT1_MAP;
1967
                        else if (c == 'U')
1968
                                G1_charset = IBMPC_MAP;
1969
                        else if (c == 'K')
1970
                                G1_charset = USER_MAP;
1971
                        if (charset == 1)
1972
                                translate = set_translate(G1_charset);
1973
                        vc_state = ESnormal;
1974
                        continue;
1975
                    default:
1976
                        vc_state = ESnormal;
1977
                }
1978
        }
1979
        if (vcmode != KD_GRAPHICS)
1980
                set_cursor(currcons);
1981
        enable_bh(CONSOLE_BH);
1982
        return n;
1983
}
1984
 
1985
static int con_write_room(struct tty_struct *tty)
1986
{
1987
        if (tty->stopped)
1988
                return 0;
1989
        return 4096;            /* No limit, really; we're not buffering */
1990
}
1991
 
1992
static int con_chars_in_buffer(struct tty_struct *tty)
1993
{
1994
        return 0;                /* we're not buffering */
1995
}
1996
 
1997
void poke_blanked_console(void)
1998
{
1999
        timer_active &= ~(1<<BLANK_TIMER);
2000
        if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
2001
                return;
2002
        if (console_blanked) {
2003
                timer_table[BLANK_TIMER].fn = unblank_screen;
2004
                timer_table[BLANK_TIMER].expires = 0;
2005
                timer_active |= 1<<BLANK_TIMER;
2006
        } else if (blankinterval) {
2007
                timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2008
                timer_active |= 1<<BLANK_TIMER;
2009
        }
2010
}
2011
 
2012
 
2013
/* DPC: New version of console_print using putcs */
2014
 
2015
void console_print(const char * b)
2016
{
2017
   int currcons = fg_console;
2018
   unsigned char c;
2019
   const char *start = b;
2020
   ushort count      = 0;
2021
   ushort myx        = x;
2022
   static int printing = 0;
2023
 
2024
   if (!printable || printing)
2025
           return;       /* console not yet initialized */
2026
   printing = 1;
2027
 
2028
   if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
2029
           currcons = kmsg_redirect - 1;
2030
 
2031
   if (!vc_cons_allocated(currcons)) {
2032
           /* impossible */
2033
           printk("console_print: tty %d not allocated ??\n", currcons+1);
2034
           printing = 0;
2035
           return;
2036
   }
2037
 
2038
   /* undraw cursor first */
2039
   hide_cursor(currcons);
2040
 
2041
   /* Contrived structure to try to emulate original need_wrap behaviour
2042
    * Problems caused when we have need_wrap set on '\n' character */
2043
 
2044
   while ((c = *(b++)) != 0) {
2045
       if (c == 10 || c == 13 || c == 8 || need_wrap) {
2046
           if ((count = b - start - 1) > 0) {
2047
               sw->con_putcs(vc_cons[currcons].d, start, count ,
2048
                             y, x);
2049
               x += count;
2050
               if (need_wrap)
2051
                 x--;
2052
           }
2053
 
2054
           if (c == 8) {        /* backspace */
2055
               bs(currcons);
2056
               start = b;
2057
               myx = x;
2058
               continue;
2059
           }
2060
           if (c != 13)
2061
               lf(currcons);
2062
           cr(currcons);
2063
 
2064
           if (c == 10 || c == 13) {
2065
               start = b; myx = x; continue;
2066
           }
2067
 
2068
           start = b-1; myx = x;
2069
       }
2070
 
2071
       *pos = c | (attr << 8);
2072
       if (myx == cols - 1) {
2073
           need_wrap = 1;
2074
           continue;
2075
       }
2076
       pos++;
2077
       myx++;
2078
   }
2079
 
2080
   if ((count = b - start -1) > 0) {
2081
       sw->con_putcs(vc_cons[currcons].d, start, count ,
2082
                     y, x);
2083
       x += count;
2084
       if (x == cols)
2085
         {
2086
           x--;
2087
           need_wrap = 1;
2088
         }
2089
   }
2090
 
2091
   set_cursor(currcons);
2092
   poke_blanked_console();
2093
   printing = 0;
2094
}
2095
 
2096
/* You didn't see this... */
2097
void console_printn(const char * b, int n)
2098
{
2099
   int i;
2100
   char buf[2];
2101
 
2102
 
2103
   buf[1] = '\0';
2104
   for(i=0;i<n;i++) {
2105
     buf[0] = *b++;
2106
     console_print(buf);
2107
   }
2108
}
2109
 
2110
/*
2111
 * con_throttle and con_unthrottle are only used for
2112
 * paste_selection(), which has to stuff in a large number of
2113
 * characters...
2114
 */
2115
static void con_throttle(struct tty_struct *tty)
2116
{
2117
}
2118
 
2119
static void con_unthrottle(struct tty_struct *tty)
2120
{
2121
        struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
2122
 
2123
        wake_up_interruptible(&vt->paste_wait);
2124
}
2125
 
2126
static void vc_init(unsigned int currcons, int do_clear)
2127
{
2128
        long base = (long) vc_scrbuf[currcons];
2129
 
2130
        pos = (unsigned short *)(origin = (ulong)video_mem_start = base);
2131
        scr_end = base + screenbuf_size;
2132
        video_mem_end = base + screenbuf_size;
2133
        reset_vc(currcons);
2134
        def_color       = 0x07;   /* white */
2135
        ulcolor         = 0x0f;   /* bold white */
2136
        halfcolor       = 0x08;   /* grey */
2137
        vt_cons[currcons]->paste_wait = 0;
2138
        reset_terminal(currcons, do_clear);
2139
}
2140
 
2141
/*
2142
 * This is the console switching bottom half handler.
2143
 *
2144
 * Doing console switching in a bottom half handler allows
2145
 * us to do the switches asynchronously (needed when we want
2146
 * to switch due to a keyboard interrupt), while still giving
2147
 * us the option to easily disable it to avoid races when we
2148
 * need to write to the console.
2149
 */
2150
static void console_bh(void)
2151
{
2152
        if (want_console >= 0) {
2153
                if (want_console != fg_console) {
2154
                        change_console(want_console);
2155
                        /* we only changed when the console had already
2156
                           been allocated - a new console is not created
2157
                           in an interrupt routine */
2158
                }
2159
                want_console = -1;
2160
        }
2161
        if (do_poke_blanked_console) { /* do not unblank for a LED change */
2162
                do_poke_blanked_console = 0;
2163
                poke_blanked_console();
2164
        }
2165
}
2166
 
2167
/*
2168
 *  unsigned long con_init(unsigned long);
2169
 *
2170
 * This routine initializes console interrupts, and does nothing
2171
 * else. If you want the screen to clear, call tty_write with
2172
 * the appropriate escape-sequence.
2173
 *
2174
 * Reads the information preserved by setup.s to determine the current display
2175
 * type and sets everything accordingly.
2176
 */
2177
unsigned long con_init(unsigned long kmem_start)
2178
{
2179
}
2180
 
2181
void vesa_powerdown_screen(void)
2182
{
2183
        int currcons = fg_console;
2184
 
2185
        timer_active &= ~(1<<BLANK_TIMER);
2186
        timer_table[BLANK_TIMER].fn = unblank_screen;
2187
 
2188
        /* Power down if currently suspended (1 or 2),
2189
         * suspend if currently blanked (0),
2190
         * else do nothing (i.e. already powered down (3)).
2191
         * Called only if powerdown features are allowed.
2192
         */
2193
        switch (vesa_blank_mode) {
2194
        case 0:
2195
                sw->con_blank(2);
2196
                break;
2197
        case 1:
2198
        case 2:
2199
                sw->con_blank(4);
2200
                break;
2201
        }
2202
}
2203
 
2204
void do_blank_screen(int nopowersave)
2205
{
2206
#if 0
2207
        int currcons;
2208
 
2209
        if (console_blanked)
2210
                return;
2211
 
2212
        if (!vc_cons_allocated(fg_console)) {
2213
                /* impossible */
2214
                printk("blank_screen: tty %d not allocated ??\n", fg_console+1);
2215
                return;
2216
        }
2217
 
2218
        /* don't blank graphics */
2219
        if (vt_cons[fg_console]->vc_mode == KD_TEXT) {
2220
                if (vesa_off_interval && !nopowersave) {
2221
                        timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
2222
                        timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
2223
                        timer_active |= (1<<BLANK_TIMER);
2224
                } else {
2225
                        timer_active &= ~(1<<BLANK_TIMER);
2226
                        timer_table[BLANK_TIMER].fn = unblank_screen;
2227
                }
2228
 
2229
                /* try not to lose information by blanking,
2230
                   and not to waste memory */
2231
                currcons = fg_console;
2232
                has_scrolled = 0;
2233
                sw->con_blank(1);
2234
                if (!nopowersave)
2235
                        sw->con_blank(vesa_blank_mode + 1);
2236
        }
2237
        else
2238
                hide_cursor(fg_console);
2239
        console_blanked = fg_console + 1;
2240
#endif
2241
}
2242
 
2243
void do_unblank_screen(void)
2244
{
2245
#if 0
2246
        int currcons;
2247
 
2248
        if (!console_blanked)
2249
                return;
2250
        if (!vc_cons_allocated(fg_console)) {
2251
                /* impossible */
2252
                printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
2253
                return;
2254
        }
2255
        timer_table[BLANK_TIMER].fn = blank_screen;
2256
        if (blankinterval) {
2257
                timer_table[BLANK_TIMER].expires = jiffies + blankinterval;
2258
                timer_active |= 1<<BLANK_TIMER;
2259
        }
2260
 
2261
        currcons = fg_console;
2262
        console_blanked = 0;
2263
        if (sw->con_blank (0))
2264
                /* Low-level driver cannot restore -> do it ourselves */
2265
                update_screen( fg_console );
2266
        set_cursor (fg_console);
2267
#endif
2268
}
2269
 
2270
void update_screen(int new_console)
2271
{
2272
        int currcons = fg_console;
2273
        int xx, yy, startx, attr_save;
2274
        char buf[256], *bufp;
2275
        unsigned short *p;
2276
        static int lock = 0;
2277
 
2278
        if (/* new_console == fg_console || */ lock)
2279
                return;
2280
        if (!vc_cons_allocated(new_console)) {
2281
                /* strange ... */
2282
                printk("update_screen: tty %d not allocated ??\n", new_console+1);
2283
                return;
2284
        }
2285
        lock = 1;
2286
 
2287
        clear_selection();
2288
 
2289
        currcons = fg_console = new_console;
2290
        sw->con_cursor (vc_cons[currcons].d, CM_ERASE);
2291
        sw->con_switch (vc_cons[new_console].d);
2292
        /* Update the screen contents */
2293
        p = video_mem_start;
2294
        attr_save = attr;
2295
        for (yy = 0; yy < rows; yy++)
2296
          {
2297
            bufp = buf;
2298
            for (startx = xx = 0; xx < cols; xx++)
2299
              {
2300
                if (attr != ((*p >> 8) & 0xff))
2301
                  {
2302
                    if (bufp > buf)
2303
                      sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
2304
                                     yy, startx);
2305
                    startx = xx;
2306
                    bufp = buf;
2307
                    attr = (*p >> 8) & 0xff;
2308
                  }
2309
                *bufp++ = *p++;
2310
                if (bufp == buf + sizeof (buf))
2311
                  {
2312
                    sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
2313
                                   yy, startx);
2314
                    startx = xx + 1;
2315
                    bufp = buf;
2316
                  }
2317
              }
2318
            if (bufp > buf)
2319
              sw->con_putcs (vc_cons[currcons].d, buf, bufp - buf,
2320
                             yy, startx);
2321
          }
2322
        set_cursor (currcons);
2323
        attr = attr_save;
2324
        set_leds();
2325
        compute_shiftstate();
2326
        lock = 0;
2327
}
2328
 
2329
/*
2330
 * If a blank_screen is due to a timer, then a power save is allowed.
2331
 * If it is related to console_switching, then avoid vesa_blank().
2332
 */
2333
static void blank_screen(void)
2334
{
2335
        do_blank_screen(0);
2336
}
2337
 
2338
static void unblank_screen(void)
2339
{
2340
        do_unblank_screen();
2341
}
2342
 
2343
/*
2344
 * Allocate the console screen memory.
2345
 */
2346
int con_open(struct tty_struct *tty, struct file * filp)
2347
{
2348
        unsigned int currcons;
2349
        int i;
2350
 
2351
        currcons = MINOR(tty->device) - tty->driver.minor_start;
2352
 
2353
        i = vc_allocate(currcons);
2354
        if (i)
2355
                return i;
2356
 
2357
        vt_cons[currcons]->vc_num = currcons;
2358
        tty->driver_data = vt_cons[currcons];
2359
 
2360
        if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2361
                tty->winsize.ws_row = rows;
2362
                tty->winsize.ws_col = cols;
2363
        }
2364
 
2365
        return 0;
2366
}
2367
 
2368
/*
2369
 * PIO_FONT support.
2370
 *
2371
 * Currently we only support 8 pixels wide fonts, at a maximum height
2372
 * of 32 pixels. Userspace fontdata is stored with 32 bytes reserved
2373
 * for each character which is kinda wasty, but this is done in order
2374
 * to maintain compatibility with the EGA/VGA fonts. It is upto the
2375
 * actual low-level console-driver convert data into its favorite
2376
 * format (maybe we should add a `fontoffset' field to the `display'
2377
 * structure so we wont have to convert the fontdata all the time.
2378
 * /Jes
2379
 */
2380
 
2381
#define cmapsz 8192
2382
 
2383
static int set_get_font(char * arg, int set, int ch512)
2384
{
2385
#ifdef CAN_LOAD_EGA_FONTS
2386
        int i, unit, size;
2387
        char *charmap;
2388
 
2389
        if (arg){
2390
                i = verify_area(set ? VERIFY_READ : VERIFY_WRITE,
2391
                                (void *)arg, ch512 ? 2*cmapsz : cmapsz);
2392
                if (i)
2393
                        return i;
2394
        }else
2395
                return -EINVAL;
2396
 
2397
 
2398
        size = ch512 ? 2*cmapsz : cmapsz;
2399
 
2400
        charmap = (char *)kmalloc(size, GFP_USER);
2401
 
2402
        if (set){
2403
                memcpy_fromfs(charmap, arg, size);
2404
 
2405
                for (unit = 32; unit > 0; unit--)
2406
                        for (i = 0; i < (ch512 ? 512 : 256); i++)
2407
                                if (charmap[32*i+unit-1])
2408
                                        goto nonzero;
2409
        nonzero:
2410
                i = conswitchp->con_set_font(vc_cons[fg_console].d, 8,
2411
                                             unit, charmap);
2412
        }else{
2413
                memset(charmap, 0, size);
2414
                i = conswitchp->con_get_font(vc_cons[fg_console].d,
2415
                                             &unit, &unit, charmap);
2416
                memcpy_tofs(arg, charmap, size);
2417
        }
2418
        kfree(charmap);
2419
 
2420
        return i;
2421
#else
2422
        return -EINVAL;
2423
#endif
2424
}
2425
 
2426
/*
2427
 * Load palette into the EGA/VGA DAC registers. arg points to a colour
2428
 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
2429
 */
2430
 
2431
int con_set_cmap (unsigned char *arg)
2432
{
2433
        return -EINVAL;
2434
}
2435
 
2436
int con_get_cmap (unsigned char *arg)
2437
{
2438
        return -EINVAL;
2439
}
2440
 
2441
void reset_palette(int currcons)
2442
{
2443
}
2444
 
2445
void set_palette(void)
2446
{
2447
}
2448
 
2449
/*
2450
 * Load font into the EGA/VGA character generator. arg points to a 8192
2451
 * byte map, 32 bytes per character. Only first H of them are used for
2452
 * 8xH fonts (0 < H <= 32).
2453
 */
2454
 
2455
int con_set_font (char *arg, int ch512)
2456
{
2457
        int i;
2458
 
2459
        i = set_get_font (arg,1,ch512);
2460
        if ( !i ) {
2461
                hashtable_contents_valid = 0;
2462
                video_mode_512ch = ch512;
2463
                console_charmask = ch512 ? 0x1ff : 0x0ff;
2464
        }
2465
        return i;
2466
}
2467
 
2468
int con_get_font (char *arg)
2469
{
2470
        return set_get_font (arg,0,video_mode_512ch);
2471
}
2472
 
2473
/*
2474
 * Adjust the screen to fit a font of a certain height
2475
 *
2476
 * Returns < 0 for error, 0 if nothing changed, and the number
2477
 * of lines on the adjusted console if changed.
2478
 */
2479
int con_adjust_height(unsigned long fontheight)
2480
{
2481
        return -EINVAL;
2482
}
2483
 
2484
void set_vesa_blanking(int arg)
2485
{
2486
        char *argp = (char *)arg + 1;
2487
        unsigned int mode = get_fs_byte(argp);
2488
        vesa_blank_mode = (mode < 4) ? mode : 0;
2489
}
2490
 
2491
unsigned long get_video_num_lines(unsigned int currcons)
2492
{
2493
        return(rows);
2494
}
2495
 
2496
unsigned long get_video_num_columns(unsigned int currcons)
2497
{
2498
        return(cols);
2499
}
2500
 
2501
unsigned long get_video_size_row(unsigned int currcons)
2502
{
2503
        return(size_row);
2504
}
2505
 
2506
/*
2507
 * Report the current status of the vc. This is exported to modules (ARub)
2508
 */
2509
 
2510
int con_get_info(int *mode, int *shift, int *col, int *row,
2511
                        struct tty_struct **tty)
2512
{
2513
        extern int shift_state;
2514
        extern struct tty_driver console_driver;
2515
        struct tty_struct **console_table=console_driver.table;
2516
 
2517
        if (mode) *mode = vt_cons[fg_console]->vc_mode;
2518
        if (shift) *shift = shift_state;
2519
        if (col) *col = video_num_columns;
2520
        if (row) *row = video_num_lines;
2521
        if (tty) *tty = console_table[fg_console];
2522
        return fg_console;
2523
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.