* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratory.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* @(#)rcons_subr.c 8.1 (Berkeley) 6/11/93
* from: $Header: rcons_subr.c,v 1.38 93/04/20 11:15:39 torek Exp $
#include <machine/fbvar.h>
#include <sparc/rcons/raster.h>
void rcons_text(struct fbdevice
*, char *, int);
void rcons_pctrl(struct fbdevice
*, int);
void rcons_esc(struct fbdevice
*, int);
void rcons_doesc(struct fbdevice
*, int);
void rcons_cursor(struct fbdevice
*);
void rcons_invert(struct fbdevice
*, int);
void rcons_clear2eop(struct fbdevice
*);
void rcons_clear2eol(struct fbdevice
*);
void rcons_scroll(struct fbdevice
*, int);
void rcons_delchar(struct fbdevice
*, int);
void rcons_delline(struct fbdevice
*, int);
void rcons_insertchar(struct fbdevice
*, int);
void rcons_insertline(struct fbdevice
*, int);
extern void rcons_bell(struct fbdevice
*);
#define RCONS_ISPRINT(c) ((c) >= ' ' && (c) <= '~')
#define RCONS_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
/* Output (or at least handle) a string sent to the console */
register struct fbdevice
*fb
;
/* XXX maybe this should be an option? */
if ((fb
->fb_bits
& FB_INESC
) == 0) {
/* Count newlines up to an escape sequence */
for (cp
= str
; j
++ < n
&& *cp
!= '\033'; ++cp
) {
/* Only jump scroll two or more rows */
if (*fb
->fb_row
+ i
>= fb
->fb_maxrow
+ 1) {
/* Erase the cursor (if necessary) */
if (fb
->fb_bits
& FB_CURSOR
)
/* Start an escape (perhaps aborting one in progress) */
fb
->fb_bits
|= FB_INESC
| FB_P0_DEFAULT
| FB_P1_DEFAULT
;
fb
->fb_bits
&= ~(FB_P0
| FB_P1
);
/* Most parameters default to 1 */
fb
->fb_p0
= fb
->fb_p1
= 1;
} else if (fb
->fb_bits
& FB_INESC
) {
/* Erase the cursor (if necessary) */
if (fb
->fb_bits
& FB_CURSOR
)
/* Display the character */
/* Try to output as much as possible */
j
= fb
->fb_maxcol
- (*fb
->fb_col
+ 1);
for (i
= 1; i
< j
&& RCONS_ISPRINT(str
[i
]); ++i
)
/* Redraw the cursor (if necessary) */
if ((fb
->fb_bits
& FB_CURSOR
) == 0)
/* Actually write a string to the frame buffer */
register struct fbdevice
*fb
;
x
= *fb
->fb_col
* fb
->fb_font
->width
+ fb
->fb_xorigin
;
y
= *fb
->fb_row
* fb
->fb_font
->height
+
fb
->fb_font_ascent
+ fb
->fb_yorigin
;
if (((fb
->fb_bits
& FB_STANDOUT
) != 0) ^
((fb
->fb_bits
& FB_INVERT
) != 0))
raster_textn(fb
->fb_sp
, x
, y
, op
, fb
->fb_font
, str
, n
);
if (*fb
->fb_col
>= fb
->fb_maxcol
) {
if (*fb
->fb_row
>= fb
->fb_maxrow
)
/* Handle a control character sent to the console */
register struct fbdevice
*fb
;
case '\r': /* Carriage return */
case '\b': /* Backspace */
case '\013': /* Vertical tab */
case '\f': /* Formfeed */
*fb
->fb_row
= *fb
->fb_col
= 0;
case '\n': /* Linefeed */
if (*fb
->fb_row
>= fb
->fb_maxrow
)
case '\t': /* Horizontal tab */
*fb
->fb_col
= (*fb
->fb_col
+ 8) & ~7;
if (*fb
->fb_col
>= fb
->fb_maxcol
)
*fb
->fb_col
= fb
->fb_maxcol
- 1;
/* Handle the next character in an escape sequence */
register struct fbdevice
*fb
;
} else if (RCONS_ISDIGIT(c
)) {
/* Add a digit to a parameter */
if (fb
->fb_bits
& FB_P0
) {
if (fb
->fb_bits
& FB_P0_DEFAULT
) {
fb
->fb_bits
&= ~FB_P0_DEFAULT
;
} else if (fb
->fb_bits
& FB_P1
) {
if (fb
->fb_bits
& FB_P1_DEFAULT
) {
fb
->fb_bits
&= ~FB_P1_DEFAULT
;
/* Erase the cursor (if necessary) */
if (fb
->fb_bits
& FB_CURSOR
)
/* Process the completed escape sequence */
fb
->fb_bits
&= ~FB_INESC
;
/* Process a complete escape sequence */
register struct fbdevice
*fb
;
/* XXX add escape sequence to enable visual (and audible) bell */
fb
->fb_bits
= FB_VISBELL
;
/* Insert Character (ICH) */
rcons_insertchar(fb
, fb
->fb_p0
);
*fb
->fb_row
-= fb
->fb_p0
;
*fb
->fb_row
+= fb
->fb_p0
;
if (*fb
->fb_row
>= fb
->fb_maxrow
)
*fb
->fb_row
= fb
->fb_maxrow
- 1;
/* Cursor Forward (CUF) */
*fb
->fb_col
+= fb
->fb_p0
;
if (*fb
->fb_col
>= fb
->fb_maxcol
)
*fb
->fb_col
= fb
->fb_maxcol
- 1;
/* Cursor Backward (CUB) */
*fb
->fb_col
-= fb
->fb_p0
;
/* Cursor Next Line (CNL) */
*fb
->fb_row
+= fb
->fb_p0
;
if (*fb
->fb_row
>= fb
->fb_maxrow
)
*fb
->fb_row
= fb
->fb_maxrow
- 1;
/* Horizontal And Vertical Position (HVP) */
/* Cursor Position (CUP) */
*fb
->fb_col
= fb
->fb_p1
- 1;
else if (*fb
->fb_col
>= fb
->fb_maxcol
)
*fb
->fb_col
= fb
->fb_maxcol
- 1;
*fb
->fb_row
= fb
->fb_p0
- 1;
else if (*fb
->fb_row
>= fb
->fb_maxrow
)
*fb
->fb_row
= fb
->fb_maxrow
- 1;
/* Erase in Display (ED) */
rcons_insertline(fb
, fb
->fb_p0
);
rcons_delline(fb
, fb
->fb_p0
);
/* Delete Character (DCH) */
rcons_delchar(fb
, fb
->fb_p0
);
/* Select Graphic Rendition (SGR); */
if (fb
->fb_bits
& FB_P0_DEFAULT
)
fb
->fb_bits
|= FB_STANDOUT
;
fb
->fb_bits
&= ~FB_STANDOUT
;
/* Black On White (SUNBOW) */
/* White On Black (SUNWOB) */
/* Set scrolling (SUNSCRL) */
if (fb
->fb_bits
& FB_P0_DEFAULT
)
/* XXX not implemented yet */
fb
->fb_scroll
= fb
->fb_p0
;
/* Reset terminal emulator (SUNRESET) */
fb
->fb_bits
&= ~FB_STANDOUT
;
if (fb
->fb_bits
& FB_INVERT
)
/* Paint (or unpaint) the cursor */
register struct fbdevice
*fb
;
x
= *fb
->fb_col
* fb
->fb_font
->width
+ fb
->fb_xorigin
;
y
= *fb
->fb_row
* fb
->fb_font
->height
+ fb
->fb_yorigin
;
raster_op(fb
->fb_sp
, x
, y
,
/* XXX This is the right way but too slow */
fb
->fb_font
->chars
[(int)' '].r
->width
,
fb
->fb_font
->chars
[(int)' '].r
->height
,
fb
->fb_font
->width
, fb
->fb_font
->height
,
RAS_INVERT
, (struct raster
*) 0, 0, 0);
fb
->fb_bits
^= FB_CURSOR
;
/* Possibly change to SUNWOB or SUNBOW mode */
if (((fb
->fb_bits
& FB_INVERT
) != 0) ^ wob
) {
raster_op(fb
->fb_sp
, 0, 0, fb
->fb_sp
->width
, fb
->fb_sp
->height
,
RAS_INVERT
, (struct raster
*) 0, 0, 0);
fb
->fb_ras_blank
= RAS_NOT(fb
->fb_ras_blank
);
fb
->fb_bits
^= FB_INVERT
;
/* Clear to the end of the page */
register struct fbdevice
*fb
;
if (*fb
->fb_col
== 0 && *fb
->fb_row
== 0) {
/* Clear the entire frame buffer */
raster_op(fb
->fb_sp
, 0, 0,
fb
->fb_sp
->width
, fb
->fb_sp
->height
,
fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);
/* Only clear what needs to be cleared */
y
= (*fb
->fb_row
+ 1) * fb
->fb_font
->height
;
raster_op(fb
->fb_sp
, fb
->fb_xorigin
, fb
->fb_yorigin
+ y
,
fb
->fb_emuwidth
, fb
->fb_emuheight
- y
,
fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);
/* Clear to the end of the line */
register struct fbdevice
*fb
;
x
= *fb
->fb_col
* fb
->fb_font
->width
;
*fb
->fb_row
* fb
->fb_font
->height
+ fb
->fb_yorigin
,
fb
->fb_emuwidth
- x
, fb
->fb_font
->height
,
fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);
register struct fbdevice
*fb
;
/* Can't scroll more than the whole screen */
/* Calculate number of pixels to scroll */
ydiv
= fb
->fb_font
->height
* n
;
raster_op(fb
->fb_sp
, fb
->fb_xorigin
, fb
->fb_yorigin
,
fb
->fb_emuwidth
, fb
->fb_emuheight
- ydiv
,
RAS_SRC
, fb
->fb_sp
, fb
->fb_xorigin
, ydiv
+ fb
->fb_yorigin
);
fb
->fb_xorigin
, fb
->fb_yorigin
+ fb
->fb_emuheight
- ydiv
,
fb
->fb_emuwidth
, ydiv
, fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);
register struct fbdevice
*fb
;
register int tox
, fromx
, y
, width
;
/* Can't delete more chars than there are */
if (n
> fb
->fb_maxcol
- *fb
->fb_col
)
n
= fb
->fb_maxcol
- *fb
->fb_col
;
fromx
= (*fb
->fb_col
+ n
) * fb
->fb_font
->width
;
tox
= *fb
->fb_col
* fb
->fb_font
->width
;
y
= *fb
->fb_row
* fb
->fb_font
->height
;
width
= n
* fb
->fb_font
->width
;
raster_op(fb
->fb_sp
, tox
+ fb
->fb_xorigin
, y
+ fb
->fb_yorigin
,
fb
->fb_emuwidth
- fromx
, fb
->fb_font
->height
,
RAS_SRC
, fb
->fb_sp
, fromx
+ fb
->fb_xorigin
, y
+ fb
->fb_yorigin
);
fb
->fb_emuwidth
- width
+ fb
->fb_xorigin
, y
+ fb
->fb_yorigin
,
width
, fb
->fb_font
->height
,
fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);
/* Delete a number of lines */
register struct fbdevice
*fb
;
register int fromy
, toy
, height
;
/* Can't delete more lines than there are */
if (n
> fb
->fb_maxrow
- *fb
->fb_row
)
n
= fb
->fb_maxrow
- *fb
->fb_row
;
fromy
= (*fb
->fb_row
+ n
) * fb
->fb_font
->height
;
toy
= *fb
->fb_row
* fb
->fb_font
->height
;
height
= fb
->fb_font
->height
* n
;
raster_op(fb
->fb_sp
, fb
->fb_xorigin
, toy
+ fb
->fb_yorigin
,
fb
->fb_emuwidth
, fb
->fb_emuheight
- fromy
, RAS_SRC
,
fb
->fb_sp
, fb
->fb_xorigin
, fromy
+ fb
->fb_yorigin
);
fb
->fb_xorigin
, fb
->fb_emuheight
- height
+ fb
->fb_yorigin
,
fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);
/* Insert some characters */
register struct fbdevice
*fb
;
register int tox
, fromx
, y
;
/* Can't insert more chars than can fit */
if (n
> fb
->fb_maxcol
- *fb
->fb_col
)
n
= fb
->fb_maxcol
- *fb
->fb_col
;
tox
= (*fb
->fb_col
+ n
) * fb
->fb_font
->width
;
fromx
= *fb
->fb_col
* fb
->fb_font
->width
;
y
= *fb
->fb_row
* fb
->fb_font
->height
;
raster_op(fb
->fb_sp
, tox
+ fb
->fb_xorigin
, y
+ fb
->fb_yorigin
,
fb
->fb_emuwidth
- tox
, fb
->fb_font
->height
,
RAS_SRC
, fb
->fb_sp
, fromx
+ fb
->fb_xorigin
, y
+ fb
->fb_yorigin
);
raster_op(fb
->fb_sp
, fromx
+ fb
->fb_xorigin
, y
+ fb
->fb_yorigin
,
fb
->fb_font
->width
* n
, fb
->fb_font
->height
,
fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);
register struct fbdevice
*fb
;
/* Can't insert more lines than can fit */
if (n
> fb
->fb_maxrow
- *fb
->fb_row
)
n
= fb
->fb_maxrow
- *fb
->fb_row
;
toy
= (*fb
->fb_row
+ n
) * fb
->fb_font
->height
;
fromy
= *fb
->fb_row
* fb
->fb_font
->height
;
raster_op(fb
->fb_sp
, fb
->fb_xorigin
, toy
+ fb
->fb_yorigin
,
fb
->fb_emuwidth
, fb
->fb_emuheight
- toy
,
RAS_SRC
, fb
->fb_sp
, fb
->fb_xorigin
, fromy
+ fb
->fb_yorigin
);
raster_op(fb
->fb_sp
, fb
->fb_xorigin
, fromy
+ fb
->fb_yorigin
,
fb
->fb_emuwidth
, fb
->fb_font
->height
* n
,
fb
->fb_ras_blank
, (struct raster
*) 0, 0, 0);