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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [video/] [console/] [promcon.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
2
 * Console driver utilizing PROM sun terminal emulation
3
 *
4
 * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
5
 * Copyright (C) 1998  Jakub Jelinek  (jj@ultra.linux.cz)
6
 */
7
 
8
#include <linux/module.h>
9
#include <linux/kernel.h>
10
#include <linux/errno.h>
11
#include <linux/string.h>
12
#include <linux/mm.h>
13
#include <linux/slab.h>
14
#include <linux/delay.h>
15
#include <linux/console.h>
16
#include <linux/vt_kern.h>
17
#include <linux/selection.h>
18
#include <linux/fb.h>
19
#include <linux/init.h>
20
#include <linux/kd.h>
21
 
22
#include <asm/oplib.h>
23
#include <asm/uaccess.h>
24
 
25
static short pw = 80 - 1, ph = 34 - 1;
26
static short px, py;
27
static unsigned long promcon_uni_pagedir[2];
28
 
29
extern u8 promfont_unicount[];
30
extern u16 promfont_unitable[];
31
 
32
#define PROMCON_COLOR 0
33
 
34
#if PROMCON_COLOR
35
#define inverted(s)     ((((s) & 0x7700) == 0x0700) ? 0 : 1)
36
#else
37
#define inverted(s)     (((s) & 0x0800) ? 1 : 0)
38
#endif
39
 
40
static __inline__ void
41
promcon_puts(char *buf, int cnt)
42
{
43
        prom_printf("%*.*s", cnt, cnt, buf);
44
}
45
 
46
static int
47
promcon_start(struct vc_data *conp, char *b)
48
{
49
        unsigned short *s = (unsigned short *)
50
                        (conp->vc_origin + py * conp->vc_size_row + (px << 1));
51
        u16 cs;
52
 
53
        cs = scr_readw(s);
54
        if (px == pw) {
55
                unsigned short *t = s - 1;
56
                u16 ct = scr_readw(t);
57
 
58
                if (inverted(cs) && inverted(ct))
59
                        return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,
60
                                       ct);
61
                else if (inverted(cs))
62
                        return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,
63
                                       ct);
64
                else if (inverted(ct))
65
                        return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,
66
                                       ct);
67
                else
68
                        return sprintf(b, "\b%c\b\033[@%c", cs, ct);
69
        }
70
 
71
        if (inverted(cs))
72
                return sprintf(b, "\033[7m%c\033[m\b", cs);
73
        else
74
                return sprintf(b, "%c\b", cs);
75
}
76
 
77
static int
78
promcon_end(struct vc_data *conp, char *b)
79
{
80
        unsigned short *s = (unsigned short *)
81
                        (conp->vc_origin + py * conp->vc_size_row + (px << 1));
82
        char *p = b;
83
        u16 cs;
84
 
85
        b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
86
 
87
        cs = scr_readw(s);
88
        if (px == pw) {
89
                unsigned short *t = s - 1;
90
                u16 ct = scr_readw(t);
91
 
92
                if (inverted(cs) && inverted(ct))
93
                        b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);
94
                else if (inverted(cs))
95
                        b += sprintf(b, "\b%c\b\033[@%c", cs, ct);
96
                else if (inverted(ct))
97
                        b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);
98
                else
99
                        b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);
100
                return b - p;
101
        }
102
 
103
        if (inverted(cs))
104
                b += sprintf(b, "%c\b", cs);
105
        else
106
                b += sprintf(b, "\033[7m%c\033[m\b", cs);
107
        return b - p;
108
}
109
 
110
const char *promcon_startup(void)
111
{
112
        const char *display_desc = "PROM";
113
        int node;
114
        char buf[40];
115
 
116
        node = prom_getchild(prom_root_node);
117
        node = prom_searchsiblings(node, "options");
118
        if (prom_getproperty(node,  "screen-#columns", buf, 40) != -1) {
119
                pw = simple_strtoul(buf, NULL, 0);
120
                if (pw < 10 || pw > 256)
121
                        pw = 80;
122
                pw--;
123
        }
124
        if (prom_getproperty(node,  "screen-#rows", buf, 40) != -1) {
125
                ph = simple_strtoul(buf, NULL, 0);
126
                if (ph < 10 || ph > 256)
127
                        ph = 34;
128
                ph--;
129
        }
130
        promcon_puts("\033[H\033[J", 6);
131
        return display_desc;
132
}
133
 
134
static void
135
promcon_init_unimap(struct vc_data *conp)
136
{
137
        mm_segment_t old_fs = get_fs();
138
        struct unipair *p, *p1;
139
        u16 *q;
140
        int i, j, k;
141
 
142
        p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);
143
        if (!p) return;
144
 
145
        q = promfont_unitable;
146
        p1 = p;
147
        k = 0;
148
        for (i = 0; i < 256; i++)
149
                for (j = promfont_unicount[i]; j; j--) {
150
                        p1->unicode = *q++;
151
                        p1->fontpos = i;
152
                        p1++;
153
                        k++;
154
                }
155
        set_fs(KERNEL_DS);
156
        con_clear_unimap(conp, NULL);
157
        con_set_unimap(conp, k, p);
158
        con_protect_unimap(conp, 1);
159
        set_fs(old_fs);
160
        kfree(p);
161
}
162
 
163
static void
164
promcon_init(struct vc_data *conp, int init)
165
{
166
        unsigned long p;
167
 
168
        conp->vc_can_do_color = PROMCON_COLOR;
169
        if (init) {
170
                conp->vc_cols = pw + 1;
171
                conp->vc_rows = ph + 1;
172
        }
173
        p = *conp->vc_uni_pagedir_loc;
174
        if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||
175
            !--conp->vc_uni_pagedir_loc[1])
176
                con_free_unimap(conp);
177
        conp->vc_uni_pagedir_loc = promcon_uni_pagedir;
178
        promcon_uni_pagedir[1]++;
179
        if (!promcon_uni_pagedir[0] && p) {
180
                promcon_init_unimap(conp);
181
        }
182
        if (!init) {
183
                if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
184
                        vc_resize(conp, pw + 1, ph + 1);
185
        }
186
}
187
 
188
static void
189
promcon_deinit(struct vc_data *conp)
190
{
191
        /* When closing the last console, reset video origin */
192
        if (!--promcon_uni_pagedir[1])
193
                con_free_unimap(conp);
194
        conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;
195
        con_set_default_unimap(conp);
196
}
197
 
198
static int
199
promcon_switch(struct vc_data *conp)
200
{
201
        return 1;
202
}
203
 
204
static unsigned short *
205
promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
206
{
207
        int cnt = pw + 1;
208
        int attr = -1;
209
        unsigned char *b = *bp;
210
 
211
        while (cnt--) {
212
                u16 c = scr_readw(s);
213
                if (attr != inverted(c)) {
214
                        attr = inverted(c);
215
                        if (attr) {
216
                                strcpy (b, "\033[7m");
217
                                b += 4;
218
                        } else {
219
                                strcpy (b, "\033[m");
220
                                b += 3;
221
                        }
222
                }
223
                *b++ = c;
224
                s++;
225
                if (b - buf >= 224) {
226
                        promcon_puts(buf, b - buf);
227
                        b = buf;
228
                }
229
        }
230
        *bp = b;
231
        return s;
232
}
233
 
234
static void
235
promcon_putcs(struct vc_data *conp, const unsigned short *s,
236
              int count, int y, int x)
237
{
238
        unsigned char buf[256], *b = buf;
239
        unsigned short attr = scr_readw(s);
240
        unsigned char save;
241
        int i, last = 0;
242
 
243
        if (console_blanked)
244
                return;
245
 
246
        if (count <= 0)
247
                return;
248
 
249
        b += promcon_start(conp, b);
250
 
251
        if (x + count >= pw + 1) {
252
                if (count == 1) {
253
                        x -= 1;
254
                        save = scr_readw((unsigned short *)(conp->vc_origin
255
                                                   + y * conp->vc_size_row
256
                                                   + (x << 1)));
257
 
258
                        if (px != x || py != y) {
259
                                b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
260
                                px = x;
261
                                py = y;
262
                        }
263
 
264
                        if (inverted(attr))
265
                                b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));
266
                        else
267
                                b += sprintf(b, "%c", scr_readw(s++));
268
 
269
                        strcpy(b, "\b\033[@");
270
                        b += 4;
271
 
272
                        if (inverted(save))
273
                                b += sprintf(b, "\033[7m%c\033[m", save);
274
                        else
275
                                b += sprintf(b, "%c", save);
276
 
277
                        px++;
278
 
279
                        b += promcon_end(conp, b);
280
                        promcon_puts(buf, b - buf);
281
                        return;
282
                } else {
283
                        last = 1;
284
                        count = pw - x - 1;
285
                }
286
        }
287
 
288
        if (inverted(attr)) {
289
                strcpy(b, "\033[7m");
290
                b += 4;
291
        }
292
 
293
        if (px != x || py != y) {
294
                b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
295
                px = x;
296
                py = y;
297
        }
298
 
299
        for (i = 0; i < count; i++) {
300
                if (b - buf >= 224) {
301
                        promcon_puts(buf, b - buf);
302
                        b = buf;
303
                }
304
                *b++ = scr_readw(s++);
305
        }
306
 
307
        px += count;
308
 
309
        if (last) {
310
                save = scr_readw(s++);
311
                b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);
312
                px++;
313
        }
314
 
315
        if (inverted(attr)) {
316
                strcpy(b, "\033[m");
317
                b += 3;
318
        }
319
 
320
        b += promcon_end(conp, b);
321
        promcon_puts(buf, b - buf);
322
}
323
 
324
static void
325
promcon_putc(struct vc_data *conp, int c, int y, int x)
326
{
327
        unsigned short s;
328
 
329
        if (console_blanked)
330
                return;
331
 
332
        scr_writew(c, &s);
333
        promcon_putcs(conp, &s, 1, y, x);
334
}
335
 
336
static void
337
promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
338
{
339
        unsigned char buf[256], *b = buf;
340
        int i, j;
341
 
342
        if (console_blanked)
343
                return;
344
 
345
        b += promcon_start(conp, b);
346
 
347
        if (!sx && width == pw + 1) {
348
 
349
                if (!sy && height == ph + 1) {
350
                        strcpy(b, "\033[H\033[J");
351
                        b += 6;
352
                        b += promcon_end(conp, b);
353
                        promcon_puts(buf, b - buf);
354
                        return;
355
                } else if (sy + height == ph + 1) {
356
                        b += sprintf(b, "\033[%dH\033[J", sy + 1);
357
                        b += promcon_end(conp, b);
358
                        promcon_puts(buf, b - buf);
359
                        return;
360
                }
361
 
362
                b += sprintf(b, "\033[%dH", sy + 1);
363
                for (i = 1; i < height; i++) {
364
                        strcpy(b, "\033[K\n");
365
                        b += 4;
366
                }
367
 
368
                strcpy(b, "\033[K");
369
                b += 3;
370
 
371
                b += promcon_end(conp, b);
372
                promcon_puts(buf, b - buf);
373
                return;
374
 
375
        } else if (sx + width == pw + 1) {
376
 
377
                b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
378
                for (i = 1; i < height; i++) {
379
                        strcpy(b, "\033[K\n");
380
                        b += 4;
381
                }
382
 
383
                strcpy(b, "\033[K");
384
                b += 3;
385
 
386
                b += promcon_end(conp, b);
387
                promcon_puts(buf, b - buf);
388
                return;
389
        }
390
 
391
        for (i = sy + 1; i <= sy + height; i++) {
392
                b += sprintf(b, "\033[%d;%dH", i, sx + 1);
393
                for (j = 0; j < width; j++)
394
                        *b++ = ' ';
395
                if (b - buf + width >= 224) {
396
                        promcon_puts(buf, b - buf);
397
                        b = buf;
398
                }
399
        }
400
 
401
        b += promcon_end(conp, b);
402
        promcon_puts(buf, b - buf);
403
}
404
 
405
static void
406
promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
407
              int height, int width)
408
{
409
        char buf[256], *b = buf;
410
 
411
        if (console_blanked)
412
                return;
413
 
414
        b += promcon_start(conp, b);
415
        if (sy == dy && height == 1) {
416
                if (dx > sx && dx + width == conp->vc_cols)
417
                        b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
418
                                     sy + 1, sx + 1, dx - sx, py + 1, px + 1);
419
                else if (dx < sx && sx + width == conp->vc_cols)
420
                        b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
421
                                     dy + 1, dx + 1, sx - dx, py + 1, px + 1);
422
 
423
                b += promcon_end(conp, b);
424
                promcon_puts(buf, b - buf);
425
                return;
426
        }
427
 
428
        /*
429
         * FIXME: What to do here???
430
         * Current console.c should not call it like that ever.
431
         */
432
        prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
433
}
434
 
435
static void
436
promcon_cursor(struct vc_data *conp, int mode)
437
{
438
        char buf[32], *b = buf;
439
 
440
        switch (mode) {
441
        case CM_ERASE:
442
                break;
443
 
444
        case CM_MOVE:
445
        case CM_DRAW:
446
                b += promcon_start(conp, b);
447
                if (px != conp->vc_x || py != conp->vc_y) {
448
                        px = conp->vc_x;
449
                        py = conp->vc_y;
450
                        b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
451
                }
452
                promcon_puts(buf, b - buf);
453
                break;
454
        }
455
}
456
 
457
static int
458
promcon_blank(struct vc_data *conp, int blank, int mode_switch)
459
{
460
        if (blank) {
461
                promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
462
                return 0;
463
        } else {
464
                /* Let console.c redraw */
465
                return 1;
466
        }
467
}
468
 
469
static int
470
promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
471
{
472
        unsigned char buf[256], *p = buf;
473
        unsigned short *s;
474
        int i;
475
 
476
        if (console_blanked)
477
                return 0;
478
 
479
        p += promcon_start(conp, p);
480
 
481
        switch (dir) {
482
        case SM_UP:
483
                if (b == ph + 1) {
484
                        p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
485
                        px = 0;
486
                        py = t;
487
                        p += promcon_end(conp, p);
488
                        promcon_puts(buf, p - buf);
489
                        break;
490
                }
491
 
492
                s = (unsigned short *)(conp->vc_origin
493
                                       + (t + count) * conp->vc_size_row);
494
 
495
                p += sprintf(p, "\033[%dH", t + 1);
496
 
497
                for (i = t; i < b - count; i++)
498
                        s = promcon_repaint_line(s, buf, &p);
499
 
500
                for (; i < b - 1; i++) {
501
                        strcpy(p, "\033[K\n");
502
                        p += 4;
503
                        if (p - buf >= 224) {
504
                                promcon_puts(buf, p - buf);
505
                                p = buf;
506
                        }
507
                }
508
 
509
                strcpy(p, "\033[K");
510
                p += 3;
511
 
512
                p += promcon_end(conp, p);
513
                promcon_puts(buf, p - buf);
514
                break;
515
 
516
        case SM_DOWN:
517
                if (b == ph + 1) {
518
                        p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
519
                        px = 0;
520
                        py = t;
521
                        p += promcon_end(conp, p);
522
                        promcon_puts(buf, p - buf);
523
                        break;
524
                }
525
 
526
                s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
527
 
528
                p += sprintf(p, "\033[%dH", t + 1);
529
 
530
                for (i = t; i < t + count; i++) {
531
                        strcpy(p, "\033[K\n");
532
                        p += 4;
533
                        if (p - buf >= 224) {
534
                                promcon_puts(buf, p - buf);
535
                                p = buf;
536
                        }
537
                }
538
 
539
                for (; i < b; i++)
540
                        s = promcon_repaint_line(s, buf, &p);
541
 
542
                p += promcon_end(conp, p);
543
                promcon_puts(buf, p - buf);
544
                break;
545
        }
546
 
547
        return 0;
548
}
549
 
550
#if !(PROMCON_COLOR)
551
static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
552
    u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
553
{
554
        return (_reverse) ? 0xf : 0x7;
555
}
556
#endif
557
 
558
/*
559
 *  The console 'switch' structure for the VGA based console
560
 */
561
 
562
static int promcon_dummy(void)
563
{
564
        return 0;
565
}
566
 
567
#define DUMMY (void *) promcon_dummy
568
 
569
const struct consw prom_con = {
570
        .owner =                THIS_MODULE,
571
        .con_startup =          promcon_startup,
572
        .con_init =             promcon_init,
573
        .con_deinit =           promcon_deinit,
574
        .con_clear =            promcon_clear,
575
        .con_putc =             promcon_putc,
576
        .con_putcs =            promcon_putcs,
577
        .con_cursor =           promcon_cursor,
578
        .con_scroll =           promcon_scroll,
579
        .con_bmove =            promcon_bmove,
580
        .con_switch =           promcon_switch,
581
        .con_blank =            promcon_blank,
582
        .con_set_palette =      DUMMY,
583
        .con_scrolldelta =      DUMMY,
584
#if !(PROMCON_COLOR)
585
        .con_build_attr =       promcon_build_attr,
586
#endif
587
};
588
 
589
void __init prom_con_init(void)
590
{
591
#ifdef CONFIG_DUMMY_CONSOLE
592
        if (conswitchp == &dummy_con)
593
                take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
594
        else
595
#endif
596
        if (conswitchp == &prom_con)
597
                promcon_init_unimap(vc_cons[fg_console].d);
598
}

powered by: WebSVN 2.1.0

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