155133Storek /*
2*63321Sbostic * Copyright (c) 1991, 1993
3*63321Sbostic * The Regents of the University of California. All rights reserved.
455133Storek *
555133Storek * This software was developed by the Computer Systems Engineering group
655133Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
755133Storek * contributed to Berkeley.
855133Storek *
955502Sbostic * All advertising materials mentioning features or use of this software
1055502Sbostic * must display the following acknowledgement:
1155502Sbostic * This product includes software developed by the University of
1259212Storek * California, Lawrence Berkeley Laboratory.
1355502Sbostic *
1455133Storek * %sccs.include.redist.c%
1555133Storek *
16*63321Sbostic * @(#)rcons_subr.c 8.1 (Berkeley) 06/11/93
1755133Storek *
1859212Storek * from: $Header: rcons_subr.c,v 1.38 93/04/20 11:15:39 torek Exp $
1955133Storek */
2055133Storek
2155133Storek #ifdef KERNEL
2256539Sbostic #include <sys/param.h>
2356539Sbostic #include <sys/fbio.h>
2456539Sbostic #include <sys/device.h>
2556539Sbostic #include <machine/fbvar.h>
2655133Storek #else
2755133Storek #include <sys/types.h>
2855133Storek #include "myfbdevice.h"
2955133Storek #endif
3055133Storek
3156539Sbostic #include <sparc/rcons/raster.h>
3255133Storek
3355133Storek void rcons_text(struct fbdevice *, char *, int);
3455133Storek void rcons_pctrl(struct fbdevice *, int);
3555133Storek void rcons_esc(struct fbdevice *, int);
3655133Storek void rcons_doesc(struct fbdevice *, int);
3755133Storek void rcons_cursor(struct fbdevice *);
3855133Storek void rcons_invert(struct fbdevice *, int);
3955133Storek void rcons_clear2eop(struct fbdevice *);
4055133Storek void rcons_clear2eol(struct fbdevice *);
4155133Storek void rcons_scroll(struct fbdevice *, int);
4255133Storek void rcons_delchar(struct fbdevice *, int);
4355133Storek void rcons_delline(struct fbdevice *, int);
4455133Storek void rcons_insertchar(struct fbdevice *, int);
4555133Storek void rcons_insertline(struct fbdevice *, int);
4655133Storek
4755133Storek extern void rcons_bell(struct fbdevice *);
4855133Storek
4955133Storek #define RCONS_ISPRINT(c) ((c) >= ' ' && (c) <= '~')
5055133Storek #define RCONS_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
5155133Storek
5255133Storek /* Output (or at least handle) a string sent to the console */
5355133Storek void
rcons_puts(fb,str,n)5455133Storek rcons_puts(fb, str, n)
5555133Storek register struct fbdevice *fb;
5655133Storek register char *str;
5755133Storek register int n;
5855133Storek {
5955133Storek register int c, i, j;
6055133Storek register char *cp;
6155133Storek
6255133Storek /* Jump scroll */
6355133Storek /* XXX maybe this should be an option? */
6455133Storek if ((fb->fb_bits & FB_INESC) == 0) {
6555133Storek /* Count newlines up to an escape sequence */
6655133Storek i = 0;
6755133Storek j = 0;
6855133Storek for (cp = str; j++ < n && *cp != '\033'; ++cp) {
6955133Storek if (*cp == '\n')
7055133Storek ++i;
7155133Storek else if (*cp == '\013')
7255133Storek --i;
7355133Storek }
7455133Storek
7555133Storek /* Only jump scroll two or more rows */
7655133Storek if (*fb->fb_row + i >= fb->fb_maxrow + 1) {
7755133Storek /* Erase the cursor (if necessary) */
7855133Storek if (fb->fb_bits & FB_CURSOR)
7955133Storek rcons_cursor(fb);
8055133Storek
8155133Storek rcons_scroll(fb, i);
8255133Storek }
8355133Storek }
8455133Storek
8555133Storek /* Process characters */
8655133Storek while (--n >= 0) {
8755133Storek c = *str;
8855133Storek if (c == '\033') {
8955133Storek /* Start an escape (perhaps aborting one in progress) */
9055133Storek fb->fb_bits |= FB_INESC | FB_P0_DEFAULT | FB_P1_DEFAULT;
9155133Storek fb->fb_bits &= ~(FB_P0 | FB_P1);
9255133Storek
9355133Storek /* Most parameters default to 1 */
9455133Storek fb->fb_p0 = fb->fb_p1 = 1;
9555133Storek } else if (fb->fb_bits & FB_INESC) {
9655133Storek rcons_esc(fb, c);
9755133Storek } else {
9855133Storek /* Erase the cursor (if necessary) */
9955133Storek if (fb->fb_bits & FB_CURSOR)
10055133Storek rcons_cursor(fb);
10155133Storek
10255133Storek /* Display the character */
10355133Storek if (RCONS_ISPRINT(c)) {
10455133Storek /* Try to output as much as possible */
10555133Storek j = fb->fb_maxcol - (*fb->fb_col + 1);
10655133Storek if (j > n)
10755133Storek j = n;
10855133Storek for (i = 1; i < j && RCONS_ISPRINT(str[i]); ++i)
10955133Storek continue;
11055133Storek rcons_text(fb, str, i);
11155133Storek --i;
11255133Storek str += i;
11355133Storek n -= i;
11455133Storek } else
11555133Storek rcons_pctrl(fb, c);
11655133Storek }
11755133Storek ++str;
11855133Storek }
11955133Storek /* Redraw the cursor (if necessary) */
12055133Storek if ((fb->fb_bits & FB_CURSOR) == 0)
12155133Storek rcons_cursor(fb);
12255133Storek }
12355133Storek
12455133Storek /* Actually write a string to the frame buffer */
12555133Storek void
rcons_text(fb,str,n)12655133Storek rcons_text(fb, str, n)
12755133Storek register struct fbdevice *fb;
12855133Storek register char *str;
12955133Storek register int n;
13055133Storek {
13155133Storek register int x, y, op;
13255133Storek
13355133Storek x = *fb->fb_col * fb->fb_font->width + fb->fb_xorigin;
13455133Storek y = *fb->fb_row * fb->fb_font->height +
13555133Storek fb->fb_font_ascent + fb->fb_yorigin;
13655133Storek op = RAS_SRC;
13755133Storek if (((fb->fb_bits & FB_STANDOUT) != 0) ^
13855133Storek ((fb->fb_bits & FB_INVERT) != 0))
13955133Storek op = RAS_NOT(op);
14055133Storek raster_textn(fb->fb_sp, x, y, op, fb->fb_font, str, n);
14155133Storek *fb->fb_col += n;
14255133Storek if (*fb->fb_col >= fb->fb_maxcol) {
14355133Storek *fb->fb_col = 0;
14455133Storek (*fb->fb_row)++;
14555133Storek }
14655133Storek if (*fb->fb_row >= fb->fb_maxrow)
14755133Storek rcons_scroll(fb, 1);
14855133Storek }
14955133Storek
15055133Storek /* Handle a control character sent to the console */
15155133Storek void
rcons_pctrl(fb,c)15255133Storek rcons_pctrl(fb, c)
15355133Storek register struct fbdevice *fb;
15455133Storek register int c;
15555133Storek {
15655133Storek
15755133Storek switch (c) {
15855133Storek
15955133Storek case '\r': /* Carriage return */
16055133Storek *fb->fb_col = 0;
16155133Storek break;
16255133Storek
16355133Storek case '\b': /* Backspace */
16455133Storek if (*fb->fb_col > 0)
16555133Storek (*fb->fb_col)--;
16655133Storek break;
16755133Storek
16855133Storek case '\013': /* Vertical tab */
16955133Storek if (*fb->fb_row > 0)
17055133Storek (*fb->fb_row)--;
17155133Storek break;
17255133Storek
17355133Storek case '\f': /* Formfeed */
17455133Storek *fb->fb_row = *fb->fb_col = 0;
17555133Storek rcons_clear2eop(fb);
17655133Storek break;
17755133Storek
17855133Storek case '\n': /* Linefeed */
17955133Storek (*fb->fb_row)++;
18055133Storek if (*fb->fb_row >= fb->fb_maxrow)
18155133Storek rcons_scroll(fb, 1);
18255133Storek break;
18355133Storek
18455133Storek case '\007': /* Bell */
18555133Storek rcons_bell(fb);
18655133Storek break;
18755133Storek
18855133Storek case '\t': /* Horizontal tab */
18955133Storek *fb->fb_col = (*fb->fb_col + 8) & ~7;
19055133Storek if (*fb->fb_col >= fb->fb_maxcol)
19155133Storek *fb->fb_col = fb->fb_maxcol - 1;
19255133Storek break;
19355133Storek }
19455133Storek }
19555133Storek
19655133Storek /* Handle the next character in an escape sequence */
19755133Storek void
rcons_esc(fb,c)19855133Storek rcons_esc(fb, c)
19955133Storek register struct fbdevice *fb;
20055133Storek register int c;
20155133Storek {
20255133Storek
20355133Storek if (c == '[') {
20455133Storek /* Parameter 0 */
20555133Storek fb->fb_bits &= ~FB_P1;
20655133Storek fb->fb_bits |= FB_P0;
20755133Storek } else if (c == ';') {
20855133Storek /* Parameter 1 */
20955133Storek fb->fb_bits &= ~FB_P0;
21055133Storek fb->fb_bits |= FB_P1;
21155133Storek } else if (RCONS_ISDIGIT(c)) {
21255133Storek /* Add a digit to a parameter */
21355133Storek if (fb->fb_bits & FB_P0) {
21455133Storek /* Parameter 0 */
21555133Storek if (fb->fb_bits & FB_P0_DEFAULT) {
21655133Storek fb->fb_bits &= ~FB_P0_DEFAULT;
21755133Storek fb->fb_p0 = 0;
21855133Storek }
21955133Storek fb->fb_p0 *= 10;
22055133Storek fb->fb_p0 += c - '0';
22155133Storek } else if (fb->fb_bits & FB_P1) {
22255133Storek /* Parameter 1 */
22355133Storek if (fb->fb_bits & FB_P1_DEFAULT) {
22455133Storek fb->fb_bits &= ~FB_P1_DEFAULT;
22555133Storek fb->fb_p1 = 0;
22655133Storek }
22755133Storek fb->fb_p1 *= 10;
22855133Storek fb->fb_p1 += c - '0';
22955133Storek }
23055133Storek } else {
23155133Storek /* Erase the cursor (if necessary) */
23255133Storek if (fb->fb_bits & FB_CURSOR)
23355133Storek rcons_cursor(fb);
23455133Storek
23555133Storek /* Process the completed escape sequence */
23655133Storek rcons_doesc(fb, c);
23755133Storek fb->fb_bits &= ~FB_INESC;
23855133Storek }
23955133Storek }
24055133Storek
24155133Storek /* Process a complete escape sequence */
24255133Storek void
rcons_doesc(fb,c)24355133Storek rcons_doesc(fb, c)
24455133Storek register struct fbdevice *fb;
24555133Storek register int c;
24655133Storek {
24755133Storek
24855133Storek #ifdef notdef
24955133Storek /* XXX add escape sequence to enable visual (and audible) bell */
25055133Storek fb->fb_bits = FB_VISBELL;
25155133Storek #endif
25255133Storek
25355133Storek switch (c) {
25455133Storek
25555133Storek case '@':
25655133Storek /* Insert Character (ICH) */
25755133Storek rcons_insertchar(fb, fb->fb_p0);
25855133Storek break;
25955133Storek
26055133Storek case 'A':
26155133Storek /* Cursor Up (CUU) */
26255133Storek *fb->fb_row -= fb->fb_p0;
26355133Storek if (*fb->fb_row < 0)
26455133Storek *fb->fb_row = 0;
26555133Storek break;
26655133Storek
26755133Storek case 'B':
26855133Storek /* Cursor Down (CUD) */
26955133Storek *fb->fb_row += fb->fb_p0;
27055133Storek if (*fb->fb_row >= fb->fb_maxrow)
27155133Storek *fb->fb_row = fb->fb_maxrow - 1;
27255133Storek break;
27355133Storek
27455133Storek case 'C':
27555133Storek /* Cursor Forward (CUF) */
27655133Storek *fb->fb_col += fb->fb_p0;
27755133Storek if (*fb->fb_col >= fb->fb_maxcol)
27855133Storek *fb->fb_col = fb->fb_maxcol - 1;
27955133Storek break;
28055133Storek
28155133Storek case 'D':
28255133Storek /* Cursor Backward (CUB) */
28355133Storek *fb->fb_col -= fb->fb_p0;
28455133Storek if (*fb->fb_col < 0)
28555133Storek *fb->fb_col = 0;
28655133Storek break;
28755133Storek
28855133Storek case 'E':
28955133Storek /* Cursor Next Line (CNL) */
29055133Storek *fb->fb_col = 0;
29155133Storek *fb->fb_row += fb->fb_p0;
29255133Storek if (*fb->fb_row >= fb->fb_maxrow)
29355133Storek *fb->fb_row = fb->fb_maxrow - 1;
29455133Storek break;
29555133Storek
29655133Storek case 'f':
29755133Storek /* Horizontal And Vertical Position (HVP) */
29855133Storek case 'H':
29955133Storek /* Cursor Position (CUP) */
30055133Storek *fb->fb_col = fb->fb_p1 - 1;
30155133Storek if (*fb->fb_col < 0)
30255133Storek *fb->fb_col = 0;
30355133Storek else if (*fb->fb_col >= fb->fb_maxcol)
30455133Storek *fb->fb_col = fb->fb_maxcol - 1;
30555133Storek
30655133Storek *fb->fb_row = fb->fb_p0 - 1;
30755133Storek if (*fb->fb_row < 0)
30855133Storek *fb->fb_row = 0;
30955133Storek else if (*fb->fb_row >= fb->fb_maxrow)
31055133Storek *fb->fb_row = fb->fb_maxrow - 1;
31155133Storek break;
31255133Storek
31355133Storek case 'J':
31455133Storek /* Erase in Display (ED) */
31555133Storek rcons_clear2eop(fb);
31655133Storek break;
31755133Storek
31855133Storek case 'K':
31955133Storek /* Erase in Line (EL) */
32055133Storek rcons_clear2eol(fb);
32155133Storek break;
32255133Storek
32355133Storek case 'L':
32455133Storek /* Insert Line (IL) */
32555133Storek rcons_insertline(fb, fb->fb_p0);
32655133Storek break;
32755133Storek
32855133Storek case 'M':
32955133Storek /* Delete Line (DL) */
33055133Storek rcons_delline(fb, fb->fb_p0);
33155133Storek break;
33255133Storek
33355133Storek case 'P':
33455133Storek /* Delete Character (DCH) */
33555133Storek rcons_delchar(fb, fb->fb_p0);
33655133Storek break;
33755133Storek
33855133Storek case 'm':
33955133Storek /* Select Graphic Rendition (SGR); */
34055133Storek /* (defaults to zero) */
34155133Storek if (fb->fb_bits & FB_P0_DEFAULT)
34255133Storek fb->fb_p0 = 0;
34355133Storek if (fb->fb_p0)
34455133Storek fb->fb_bits |= FB_STANDOUT;
34555133Storek else
34655133Storek fb->fb_bits &= ~FB_STANDOUT;
34755133Storek break;
34855133Storek
34955133Storek case 'p':
35055133Storek /* Black On White (SUNBOW) */
35155133Storek rcons_invert(fb, 0);
35255133Storek break;
35355133Storek
35455133Storek case 'q':
35555133Storek /* White On Black (SUNWOB) */
35655133Storek rcons_invert(fb, 1);
35755133Storek break;
35855133Storek
35955133Storek case 'r':
36055133Storek /* Set scrolling (SUNSCRL) */
36155133Storek /* (defaults to zero) */
36255133Storek if (fb->fb_bits & FB_P0_DEFAULT)
36355133Storek fb->fb_p0 = 0;
36455133Storek /* XXX not implemented yet */
36555133Storek fb->fb_scroll = fb->fb_p0;
36655133Storek break;
36755133Storek
36855133Storek case 's':
36955133Storek /* Reset terminal emulator (SUNRESET) */
37055133Storek fb->fb_bits &= ~FB_STANDOUT;
37155133Storek fb->fb_scroll = 0;
37255133Storek if (fb->fb_bits & FB_INVERT)
37355133Storek rcons_invert(fb, 0);
37455133Storek break;
37555133Storek }
37655133Storek }
37755133Storek
37855133Storek /* Paint (or unpaint) the cursor */
37955133Storek void
rcons_cursor(fb)38055133Storek rcons_cursor(fb)
38155133Storek register struct fbdevice *fb;
38255133Storek {
38355133Storek register int x, y;
38455133Storek
38555133Storek x = *fb->fb_col * fb->fb_font->width + fb->fb_xorigin;
38655133Storek y = *fb->fb_row * fb->fb_font->height + fb->fb_yorigin;
38755133Storek raster_op(fb->fb_sp, x, y,
38855133Storek #ifdef notdef
38955133Storek /* XXX This is the right way but too slow */
39055133Storek fb->fb_font->chars[(int)' '].r->width,
39155133Storek fb->fb_font->chars[(int)' '].r->height,
39255133Storek #else
39355133Storek fb->fb_font->width, fb->fb_font->height,
39455133Storek #endif
39555133Storek RAS_INVERT, (struct raster *) 0, 0, 0);
39655133Storek fb->fb_bits ^= FB_CURSOR;
39755133Storek }
39855133Storek
39955133Storek /* Possibly change to SUNWOB or SUNBOW mode */
40055133Storek void
rcons_invert(fb,wob)40155133Storek rcons_invert(fb, wob)
40255133Storek struct fbdevice *fb;
40355133Storek int wob;
40455133Storek {
40555133Storek if (((fb->fb_bits & FB_INVERT) != 0) ^ wob) {
40655133Storek /* Invert the display */
40755133Storek raster_op(fb->fb_sp, 0, 0, fb->fb_sp->width, fb->fb_sp->height,
40855133Storek RAS_INVERT, (struct raster *) 0, 0, 0);
40955133Storek
41055133Storek /* Swap things around */
41155133Storek fb->fb_ras_blank = RAS_NOT(fb->fb_ras_blank);
41255133Storek fb->fb_bits ^= FB_INVERT;
41355133Storek }
41455133Storek }
41555133Storek
41655133Storek /* Clear to the end of the page */
41755133Storek void
rcons_clear2eop(fb)41855133Storek rcons_clear2eop(fb)
41955133Storek register struct fbdevice *fb;
42055133Storek {
42155133Storek register int y;
42255133Storek
42355133Storek if (*fb->fb_col == 0 && *fb->fb_row == 0) {
42455133Storek /* Clear the entire frame buffer */
42555133Storek raster_op(fb->fb_sp, 0, 0,
42655133Storek fb->fb_sp->width, fb->fb_sp->height,
42755133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0);
42855133Storek } else {
42955133Storek /* Only clear what needs to be cleared */
43055133Storek rcons_clear2eol(fb);
43155133Storek y = (*fb->fb_row + 1) * fb->fb_font->height;
43255133Storek
43355133Storek raster_op(fb->fb_sp, fb->fb_xorigin, fb->fb_yorigin + y,
43455133Storek fb->fb_emuwidth, fb->fb_emuheight - y,
43555133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0);
43655133Storek }
43755133Storek }
43855133Storek
43955133Storek /* Clear to the end of the line */
44055133Storek void
rcons_clear2eol(fb)44155133Storek rcons_clear2eol(fb)
44255133Storek register struct fbdevice *fb;
44355133Storek {
44455133Storek register int x;
44555133Storek
44655133Storek x = *fb->fb_col * fb->fb_font->width;
44755133Storek
44855133Storek raster_op(fb->fb_sp,
44955133Storek fb->fb_xorigin + x,
45055133Storek *fb->fb_row * fb->fb_font->height + fb->fb_yorigin,
45155133Storek fb->fb_emuwidth - x, fb->fb_font->height,
45255133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0);
45355133Storek }
45455133Storek
45555133Storek /* Scroll up one line */
45655133Storek void
rcons_scroll(fb,n)45755133Storek rcons_scroll(fb, n)
45855133Storek register struct fbdevice *fb;
45955133Storek register int n;
46055133Storek {
46155133Storek register int ydiv;
46255133Storek
46355133Storek /* Can't scroll more than the whole screen */
46455133Storek if (n > fb->fb_maxrow)
46555133Storek n = fb->fb_maxrow;
46655133Storek
46755133Storek /* Calculate new row */
46855133Storek *fb->fb_row -= n;
46955133Storek if (*fb->fb_row < 0)
47055133Storek *fb->fb_row = 0;
47155133Storek
47255133Storek /* Calculate number of pixels to scroll */
47355133Storek ydiv = fb->fb_font->height * n;
47455133Storek
47555133Storek raster_op(fb->fb_sp, fb->fb_xorigin, fb->fb_yorigin,
47655133Storek fb->fb_emuwidth, fb->fb_emuheight - ydiv,
47755133Storek RAS_SRC, fb->fb_sp, fb->fb_xorigin, ydiv + fb->fb_yorigin);
47855133Storek
47955133Storek raster_op(fb->fb_sp,
48055133Storek fb->fb_xorigin, fb->fb_yorigin + fb->fb_emuheight - ydiv,
48155133Storek fb->fb_emuwidth, ydiv, fb->fb_ras_blank, (struct raster *) 0, 0, 0);
48255133Storek }
48355133Storek
48455133Storek /* Delete characters */
48555133Storek void
rcons_delchar(fb,n)48655133Storek rcons_delchar(fb, n)
48755133Storek register struct fbdevice *fb;
48855133Storek register int n;
48955133Storek {
49055133Storek register int tox, fromx, y, width;
49155133Storek
49255133Storek /* Can't delete more chars than there are */
49355133Storek if (n > fb->fb_maxcol - *fb->fb_col)
49455133Storek n = fb->fb_maxcol - *fb->fb_col;
49555133Storek
49655133Storek fromx = (*fb->fb_col + n) * fb->fb_font->width;
49755133Storek tox = *fb->fb_col * fb->fb_font->width;
49855133Storek y = *fb->fb_row * fb->fb_font->height;
49955133Storek width = n * fb->fb_font->width;
50055133Storek
50155133Storek raster_op(fb->fb_sp, tox + fb->fb_xorigin, y + fb->fb_yorigin,
50255133Storek fb->fb_emuwidth - fromx, fb->fb_font->height,
50355133Storek RAS_SRC, fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin);
50455133Storek
50555133Storek raster_op(fb->fb_sp,
50655133Storek fb->fb_emuwidth - width + fb->fb_xorigin, y + fb->fb_yorigin,
50755133Storek width, fb->fb_font->height,
50855133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0);
50955133Storek }
51055133Storek
51155133Storek /* Delete a number of lines */
51255133Storek void
rcons_delline(fb,n)51355133Storek rcons_delline(fb, n)
51455133Storek register struct fbdevice *fb;
51555133Storek register int n;
51655133Storek {
51755133Storek register int fromy, toy, height;
51855133Storek
51955133Storek /* Can't delete more lines than there are */
52055133Storek if (n > fb->fb_maxrow - *fb->fb_row)
52155133Storek n = fb->fb_maxrow - *fb->fb_row;
52255133Storek
52355133Storek fromy = (*fb->fb_row + n) * fb->fb_font->height;
52455133Storek toy = *fb->fb_row * fb->fb_font->height;
52555133Storek height = fb->fb_font->height * n;
52655133Storek
52755133Storek raster_op(fb->fb_sp, fb->fb_xorigin, toy + fb->fb_yorigin,
52855133Storek fb->fb_emuwidth, fb->fb_emuheight - fromy, RAS_SRC,
52955133Storek fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin);
53055133Storek
53155133Storek raster_op(fb->fb_sp,
53255133Storek fb->fb_xorigin, fb->fb_emuheight - height + fb->fb_yorigin,
53355133Storek fb->fb_emuwidth, height,
53455133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0);
53555133Storek }
53655133Storek
53755133Storek /* Insert some characters */
53855133Storek void
rcons_insertchar(fb,n)53955133Storek rcons_insertchar(fb, n)
54055133Storek register struct fbdevice *fb;
54155133Storek register int n;
54255133Storek {
54355133Storek register int tox, fromx, y;
54455133Storek
54555133Storek /* Can't insert more chars than can fit */
54655133Storek if (n > fb->fb_maxcol - *fb->fb_col)
54755133Storek n = fb->fb_maxcol - *fb->fb_col;
54855133Storek
54955133Storek tox = (*fb->fb_col + n) * fb->fb_font->width;
55055133Storek fromx = *fb->fb_col * fb->fb_font->width;
55155133Storek y = *fb->fb_row * fb->fb_font->height;
55255133Storek
55355133Storek raster_op(fb->fb_sp, tox + fb->fb_xorigin, y + fb->fb_yorigin,
55455133Storek fb->fb_emuwidth - tox, fb->fb_font->height,
55555133Storek RAS_SRC, fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin);
55655133Storek
55755133Storek raster_op(fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin,
55855133Storek fb->fb_font->width * n, fb->fb_font->height,
55955133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0);
56055133Storek }
56155133Storek
56255133Storek /* Insert some lines */
56355133Storek void
rcons_insertline(fb,n)56455133Storek rcons_insertline(fb, n)
56555133Storek register struct fbdevice *fb;
56655133Storek register int n;
56755133Storek {
56855133Storek register int fromy, toy;
56955133Storek
57055133Storek /* Can't insert more lines than can fit */
57155133Storek if (n > fb->fb_maxrow - *fb->fb_row)
57255133Storek n = fb->fb_maxrow - *fb->fb_row;
57355133Storek
57455133Storek toy = (*fb->fb_row + n) * fb->fb_font->height;
57555133Storek fromy = *fb->fb_row * fb->fb_font->height;
57655133Storek
57755133Storek raster_op(fb->fb_sp, fb->fb_xorigin, toy + fb->fb_yorigin,
57855133Storek fb->fb_emuwidth, fb->fb_emuheight - toy,
57955133Storek RAS_SRC, fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin);
58055133Storek
58155133Storek raster_op(fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin,
58255133Storek fb->fb_emuwidth, fb->fb_font->height * n,
58355133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0);
58455133Storek }
585