155133Storek /* 255133Storek * Copyright (c) 1991 The Regents of the University of California. 355133Storek * 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 * 9*55502Sbostic * All advertising materials mentioning features or use of this software 10*55502Sbostic * must display the following acknowledgement: 11*55502Sbostic * This product includes software developed by the University of 12*55502Sbostic * California, Lawrence Berkeley Laboratories. 13*55502Sbostic * 1455133Storek * %sccs.include.redist.c% 1555133Storek * 16*55502Sbostic * @(#)rcons_subr.c 7.2 (Berkeley) 07/21/92 1755133Storek * 1855133Storek * from: $Header: rcons_subr.c,v 1.36 92/06/17 06:23:39 torek Exp $ 1955133Storek */ 2055133Storek 2155133Storek #ifdef KERNEL 2255133Storek #include "sys/param.h" 2355133Storek #include "sys/fbio.h" 2455133Storek #include "sys/device.h" 2555133Storek #include "machine/fbvar.h" 2655133Storek #else 2755133Storek #include <sys/types.h> 2855133Storek #include "myfbdevice.h" 2955133Storek #endif 3055133Storek 3155133Storek #include "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 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 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 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 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 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 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 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 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 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 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 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 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 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 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