1 /* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
2 * Console driver utilizing PROM sun terminal emulation
4 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
5 * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/string.h>
13 #include <linux/tty.h>
14 #include <linux/slab.h>
15 #include <linux/delay.h>
16 #include <linux/console.h>
17 #include <linux/vt_kern.h>
18 #include <linux/selection.h>
20 #include <linux/init.h>
23 #include <asm/oplib.h>
24 #include <asm/uaccess.h>
26 static short pw
= 80 - 1, ph
= 34 - 1;
28 static unsigned long promcon_uni_pagedir
[2];
30 extern u8 promfont_unicount
[];
31 extern u16 promfont_unitable
[];
33 #define PROMCON_COLOR 0
36 #define inverted(s) ((((s) & 0x7700) == 0x0700) ? 0 : 1)
38 #define inverted(s) (((s) & 0x0800) ? 1 : 0)
41 static __inline__
void
42 promcon_puts(char *buf
, int cnt
)
44 prom_printf("%*.*s", cnt
, cnt
, buf
);
48 promcon_start(struct vc_data
*conp
, char *b
)
50 unsigned short *s
= (unsigned short *)
51 (conp
->vc_origin
+ py
* conp
->vc_size_row
+ (px
<< 1));
56 unsigned short *t
= s
- 1;
57 u16 ct
= scr_readw(t
);
59 if (inverted(cs
) && inverted(ct
))
60 return sprintf(b
, "\b\033[7m%c\b\033[@%c\033[m", cs
,
62 else if (inverted(cs
))
63 return sprintf(b
, "\b\033[7m%c\033[m\b\033[@%c", cs
,
65 else if (inverted(ct
))
66 return sprintf(b
, "\b%c\b\033[@\033[7m%c\033[m", cs
,
69 return sprintf(b
, "\b%c\b\033[@%c", cs
, ct
);
73 return sprintf(b
, "\033[7m%c\033[m\b", cs
);
75 return sprintf(b
, "%c\b", cs
);
79 promcon_end(struct vc_data
*conp
, char *b
)
81 unsigned short *s
= (unsigned short *)
82 (conp
->vc_origin
+ py
* conp
->vc_size_row
+ (px
<< 1));
86 b
+= sprintf(b
, "\033[%d;%dH", py
+ 1, px
+ 1);
90 unsigned short *t
= s
- 1;
91 u16 ct
= scr_readw(t
);
93 if (inverted(cs
) && inverted(ct
))
94 b
+= sprintf(b
, "\b%c\b\033[@\033[7m%c\033[m", cs
, ct
);
95 else if (inverted(cs
))
96 b
+= sprintf(b
, "\b%c\b\033[@%c", cs
, ct
);
97 else if (inverted(ct
))
98 b
+= sprintf(b
, "\b\033[7m%c\b\033[@%c\033[m", cs
, ct
);
100 b
+= sprintf(b
, "\b\033[7m%c\033[m\b\033[@%c", cs
, ct
);
105 b
+= sprintf(b
, "%c\b", cs
);
107 b
+= sprintf(b
, "\033[7m%c\033[m\b", cs
);
111 const char *promcon_startup(void)
113 const char *display_desc
= "PROM";
117 node
= prom_getchild(prom_root_node
);
118 node
= prom_searchsiblings(node
, "options");
119 if (prom_getproperty(node
, "screen-#columns", buf
, 40) != -1) {
120 pw
= simple_strtoul(buf
, NULL
, 0);
121 if (pw
< 10 || pw
> 256)
125 if (prom_getproperty(node
, "screen-#rows", buf
, 40) != -1) {
126 ph
= simple_strtoul(buf
, NULL
, 0);
127 if (ph
< 10 || ph
> 256)
131 promcon_puts("\033[H\033[J", 6);
136 promcon_init_unimap(struct vc_data
*conp
)
138 mm_segment_t old_fs
= get_fs();
139 struct unipair
*p
, *p1
;
143 p
= kmalloc(256*sizeof(struct unipair
), GFP_KERNEL
);
146 q
= promfont_unitable
;
149 for (i
= 0; i
< 256; i
++)
150 for (j
= promfont_unicount
[i
]; j
; j
--) {
157 con_clear_unimap(conp
, NULL
);
158 con_set_unimap(conp
, k
, p
);
159 con_protect_unimap(conp
, 1);
165 promcon_init(struct vc_data
*conp
, int init
)
169 conp
->vc_can_do_color
= PROMCON_COLOR
;
171 conp
->vc_cols
= pw
+ 1;
172 conp
->vc_rows
= ph
+ 1;
174 p
= *conp
->vc_uni_pagedir_loc
;
175 if (conp
->vc_uni_pagedir_loc
== &conp
->vc_uni_pagedir
||
176 !--conp
->vc_uni_pagedir_loc
[1])
177 con_free_unimap(conp
);
178 conp
->vc_uni_pagedir_loc
= promcon_uni_pagedir
;
179 promcon_uni_pagedir
[1]++;
180 if (!promcon_uni_pagedir
[0] && p
) {
181 promcon_init_unimap(conp
);
184 if (conp
->vc_cols
!= pw
+ 1 || conp
->vc_rows
!= ph
+ 1)
185 vc_resize(conp
, pw
+ 1, ph
+ 1);
190 promcon_deinit(struct vc_data
*conp
)
192 /* When closing the last console, reset video origin */
193 if (!--promcon_uni_pagedir
[1])
194 con_free_unimap(conp
);
195 conp
->vc_uni_pagedir_loc
= &conp
->vc_uni_pagedir
;
196 con_set_default_unimap(conp
);
200 promcon_switch(struct vc_data
*conp
)
205 static unsigned short *
206 promcon_repaint_line(unsigned short *s
, unsigned char *buf
, unsigned char **bp
)
210 unsigned char *b
= *bp
;
213 u16 c
= scr_readw(s
);
214 if (attr
!= inverted(c
)) {
217 strcpy (b
, "\033[7m");
220 strcpy (b
, "\033[m");
226 if (b
- buf
>= 224) {
227 promcon_puts(buf
, b
- buf
);
236 promcon_putcs(struct vc_data
*conp
, const unsigned short *s
,
237 int count
, int y
, int x
)
239 unsigned char buf
[256], *b
= buf
;
240 unsigned short attr
= scr_readw(s
);
250 b
+= promcon_start(conp
, b
);
252 if (x
+ count
>= pw
+ 1) {
255 save
= scr_readw((unsigned short *)(conp
->vc_origin
256 + y
* conp
->vc_size_row
259 if (px
!= x
|| py
!= y
) {
260 b
+= sprintf(b
, "\033[%d;%dH", y
+ 1, x
+ 1);
266 b
+= sprintf(b
, "\033[7m%c\033[m", scr_readw(s
++));
268 b
+= sprintf(b
, "%c", scr_readw(s
++));
270 strcpy(b
, "\b\033[@");
274 b
+= sprintf(b
, "\033[7m%c\033[m", save
);
276 b
+= sprintf(b
, "%c", save
);
280 b
+= promcon_end(conp
, b
);
281 promcon_puts(buf
, b
- buf
);
289 if (inverted(attr
)) {
290 strcpy(b
, "\033[7m");
294 if (px
!= x
|| py
!= y
) {
295 b
+= sprintf(b
, "\033[%d;%dH", y
+ 1, x
+ 1);
300 for (i
= 0; i
< count
; i
++) {
301 if (b
- buf
>= 224) {
302 promcon_puts(buf
, b
- buf
);
305 *b
++ = scr_readw(s
++);
311 save
= scr_readw(s
++);
312 b
+= sprintf(b
, "%c\b\033[@%c", scr_readw(s
++), save
);
316 if (inverted(attr
)) {
321 b
+= promcon_end(conp
, b
);
322 promcon_puts(buf
, b
- buf
);
326 promcon_putc(struct vc_data
*conp
, int c
, int y
, int x
)
334 promcon_putcs(conp
, &s
, 1, y
, x
);
338 promcon_clear(struct vc_data
*conp
, int sy
, int sx
, int height
, int width
)
340 unsigned char buf
[256], *b
= buf
;
346 b
+= promcon_start(conp
, b
);
348 if (!sx
&& width
== pw
+ 1) {
350 if (!sy
&& height
== ph
+ 1) {
351 strcpy(b
, "\033[H\033[J");
353 b
+= promcon_end(conp
, b
);
354 promcon_puts(buf
, b
- buf
);
356 } else if (sy
+ height
== ph
+ 1) {
357 b
+= sprintf(b
, "\033[%dH\033[J", sy
+ 1);
358 b
+= promcon_end(conp
, b
);
359 promcon_puts(buf
, b
- buf
);
363 b
+= sprintf(b
, "\033[%dH", sy
+ 1);
364 for (i
= 1; i
< height
; i
++) {
365 strcpy(b
, "\033[K\n");
372 b
+= promcon_end(conp
, b
);
373 promcon_puts(buf
, b
- buf
);
376 } else if (sx
+ width
== pw
+ 1) {
378 b
+= sprintf(b
, "\033[%d;%dH", sy
+ 1, sx
+ 1);
379 for (i
= 1; i
< height
; i
++) {
380 strcpy(b
, "\033[K\n");
387 b
+= promcon_end(conp
, b
);
388 promcon_puts(buf
, b
- buf
);
392 for (i
= sy
+ 1; i
<= sy
+ height
; i
++) {
393 b
+= sprintf(b
, "\033[%d;%dH", i
, sx
+ 1);
394 for (j
= 0; j
< width
; j
++)
396 if (b
- buf
+ width
>= 224) {
397 promcon_puts(buf
, b
- buf
);
402 b
+= promcon_end(conp
, b
);
403 promcon_puts(buf
, b
- buf
);
407 promcon_bmove(struct vc_data
*conp
, int sy
, int sx
, int dy
, int dx
,
408 int height
, int width
)
410 char buf
[256], *b
= buf
;
415 b
+= promcon_start(conp
, b
);
416 if (sy
== dy
&& height
== 1) {
417 if (dx
> sx
&& dx
+ width
== conp
->vc_cols
)
418 b
+= sprintf(b
, "\033[%d;%dH\033[%d@\033[%d;%dH",
419 sy
+ 1, sx
+ 1, dx
- sx
, py
+ 1, px
+ 1);
420 else if (dx
< sx
&& sx
+ width
== conp
->vc_cols
)
421 b
+= sprintf(b
, "\033[%d;%dH\033[%dP\033[%d;%dH",
422 dy
+ 1, dx
+ 1, sx
- dx
, py
+ 1, px
+ 1);
424 b
+= promcon_end(conp
, b
);
425 promcon_puts(buf
, b
- buf
);
430 * FIXME: What to do here???
431 * Current console.c should not call it like that ever.
433 prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
437 promcon_cursor(struct vc_data
*conp
, int mode
)
439 char buf
[32], *b
= buf
;
447 b
+= promcon_start(conp
, b
);
448 if (px
!= conp
->vc_x
|| py
!= conp
->vc_y
) {
451 b
+= sprintf(b
, "\033[%d;%dH", py
+ 1, px
+ 1);
453 promcon_puts(buf
, b
- buf
);
459 promcon_blank(struct vc_data
*conp
, int blank
, int mode_switch
)
462 promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
465 /* Let console.c redraw */
471 promcon_scroll(struct vc_data
*conp
, int t
, int b
, int dir
, int count
)
473 unsigned char buf
[256], *p
= buf
;
480 p
+= promcon_start(conp
, p
);
485 p
+= sprintf(p
, "\033[%dH\033[%dM", t
+ 1, count
);
488 p
+= promcon_end(conp
, p
);
489 promcon_puts(buf
, p
- buf
);
493 s
= (unsigned short *)(conp
->vc_origin
494 + (t
+ count
) * conp
->vc_size_row
);
496 p
+= sprintf(p
, "\033[%dH", t
+ 1);
498 for (i
= t
; i
< b
- count
; i
++)
499 s
= promcon_repaint_line(s
, buf
, &p
);
501 for (; i
< b
- 1; i
++) {
502 strcpy(p
, "\033[K\n");
504 if (p
- buf
>= 224) {
505 promcon_puts(buf
, p
- buf
);
513 p
+= promcon_end(conp
, p
);
514 promcon_puts(buf
, p
- buf
);
519 p
+= sprintf(p
, "\033[%dH\033[%dL", t
+ 1, count
);
522 p
+= promcon_end(conp
, p
);
523 promcon_puts(buf
, p
- buf
);
527 s
= (unsigned short *)(conp
->vc_origin
+ t
* conp
->vc_size_row
);
529 p
+= sprintf(p
, "\033[%dH", t
+ 1);
531 for (i
= t
; i
< t
+ count
; i
++) {
532 strcpy(p
, "\033[K\n");
534 if (p
- buf
>= 224) {
535 promcon_puts(buf
, p
- buf
);
541 s
= promcon_repaint_line(s
, buf
, &p
);
543 p
+= promcon_end(conp
, p
);
544 promcon_puts(buf
, p
- buf
);
552 static u8
promcon_build_attr(struct vc_data
*conp
, u8 _color
, u8 _intensity
, u8 _blink
, u8 _underline
, u8 _reverse
)
554 return (_reverse
) ? 0xf : 0x7;
559 * The console 'switch' structure for the VGA based console
562 static int promcon_dummy(void)
567 #define DUMMY (void *) promcon_dummy
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
,
585 .con_build_attr
= promcon_build_attr
,
589 void __init
prom_con_init(void)
591 #ifdef CONFIG_DUMMY_CONSOLE
592 if (conswitchp
== &dummy_con
)
593 take_over_console(&prom_con
, 0, MAX_NR_CONSOLES
-1, 1);
596 if (conswitchp
== &prom_con
)
597 promcon_init_unimap(vc_cons
[fg_console
].d
);
This page took 0.043164 seconds and 6 git commands to generate.