1*55133Storek /* 2*55133Storek * Copyright (c) 1991 The Regents of the University of California. 3*55133Storek * All rights reserved. 4*55133Storek * 5*55133Storek * This software was developed by the Computer Systems Engineering group 6*55133Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7*55133Storek * contributed to Berkeley. 8*55133Storek * 9*55133Storek * %sccs.include.redist.c% 10*55133Storek * 11*55133Storek * @(#)rcons_subr.c 7.1 (Berkeley) 07/13/92 12*55133Storek * 13*55133Storek * from: $Header: rcons_subr.c,v 1.36 92/06/17 06:23:39 torek Exp $ 14*55133Storek */ 15*55133Storek 16*55133Storek #ifdef KERNEL 17*55133Storek #include "sys/param.h" 18*55133Storek #include "sys/fbio.h" 19*55133Storek #include "sys/device.h" 20*55133Storek #include "machine/fbvar.h" 21*55133Storek #else 22*55133Storek #include <sys/types.h> 23*55133Storek #include "myfbdevice.h" 24*55133Storek #endif 25*55133Storek 26*55133Storek #include "raster.h" 27*55133Storek 28*55133Storek void rcons_text(struct fbdevice *, char *, int); 29*55133Storek void rcons_pctrl(struct fbdevice *, int); 30*55133Storek void rcons_esc(struct fbdevice *, int); 31*55133Storek void rcons_doesc(struct fbdevice *, int); 32*55133Storek void rcons_cursor(struct fbdevice *); 33*55133Storek void rcons_invert(struct fbdevice *, int); 34*55133Storek void rcons_clear2eop(struct fbdevice *); 35*55133Storek void rcons_clear2eol(struct fbdevice *); 36*55133Storek void rcons_scroll(struct fbdevice *, int); 37*55133Storek void rcons_delchar(struct fbdevice *, int); 38*55133Storek void rcons_delline(struct fbdevice *, int); 39*55133Storek void rcons_insertchar(struct fbdevice *, int); 40*55133Storek void rcons_insertline(struct fbdevice *, int); 41*55133Storek 42*55133Storek extern void rcons_bell(struct fbdevice *); 43*55133Storek 44*55133Storek #define RCONS_ISPRINT(c) ((c) >= ' ' && (c) <= '~') 45*55133Storek #define RCONS_ISDIGIT(c) ((c) >= '0' && (c) <= '9') 46*55133Storek 47*55133Storek /* Output (or at least handle) a string sent to the console */ 48*55133Storek void 49*55133Storek rcons_puts(fb, str, n) 50*55133Storek register struct fbdevice *fb; 51*55133Storek register char *str; 52*55133Storek register int n; 53*55133Storek { 54*55133Storek register int c, i, j; 55*55133Storek register char *cp; 56*55133Storek 57*55133Storek /* Jump scroll */ 58*55133Storek /* XXX maybe this should be an option? */ 59*55133Storek if ((fb->fb_bits & FB_INESC) == 0) { 60*55133Storek /* Count newlines up to an escape sequence */ 61*55133Storek i = 0; 62*55133Storek j = 0; 63*55133Storek for (cp = str; j++ < n && *cp != '\033'; ++cp) { 64*55133Storek if (*cp == '\n') 65*55133Storek ++i; 66*55133Storek else if (*cp == '\013') 67*55133Storek --i; 68*55133Storek } 69*55133Storek 70*55133Storek /* Only jump scroll two or more rows */ 71*55133Storek if (*fb->fb_row + i >= fb->fb_maxrow + 1) { 72*55133Storek /* Erase the cursor (if necessary) */ 73*55133Storek if (fb->fb_bits & FB_CURSOR) 74*55133Storek rcons_cursor(fb); 75*55133Storek 76*55133Storek rcons_scroll(fb, i); 77*55133Storek } 78*55133Storek } 79*55133Storek 80*55133Storek /* Process characters */ 81*55133Storek while (--n >= 0) { 82*55133Storek c = *str; 83*55133Storek if (c == '\033') { 84*55133Storek /* Start an escape (perhaps aborting one in progress) */ 85*55133Storek fb->fb_bits |= FB_INESC | FB_P0_DEFAULT | FB_P1_DEFAULT; 86*55133Storek fb->fb_bits &= ~(FB_P0 | FB_P1); 87*55133Storek 88*55133Storek /* Most parameters default to 1 */ 89*55133Storek fb->fb_p0 = fb->fb_p1 = 1; 90*55133Storek } else if (fb->fb_bits & FB_INESC) { 91*55133Storek rcons_esc(fb, c); 92*55133Storek } else { 93*55133Storek /* Erase the cursor (if necessary) */ 94*55133Storek if (fb->fb_bits & FB_CURSOR) 95*55133Storek rcons_cursor(fb); 96*55133Storek 97*55133Storek /* Display the character */ 98*55133Storek if (RCONS_ISPRINT(c)) { 99*55133Storek /* Try to output as much as possible */ 100*55133Storek j = fb->fb_maxcol - (*fb->fb_col + 1); 101*55133Storek if (j > n) 102*55133Storek j = n; 103*55133Storek for (i = 1; i < j && RCONS_ISPRINT(str[i]); ++i) 104*55133Storek continue; 105*55133Storek rcons_text(fb, str, i); 106*55133Storek --i; 107*55133Storek str += i; 108*55133Storek n -= i; 109*55133Storek } else 110*55133Storek rcons_pctrl(fb, c); 111*55133Storek } 112*55133Storek ++str; 113*55133Storek } 114*55133Storek /* Redraw the cursor (if necessary) */ 115*55133Storek if ((fb->fb_bits & FB_CURSOR) == 0) 116*55133Storek rcons_cursor(fb); 117*55133Storek } 118*55133Storek 119*55133Storek /* Actually write a string to the frame buffer */ 120*55133Storek void 121*55133Storek rcons_text(fb, str, n) 122*55133Storek register struct fbdevice *fb; 123*55133Storek register char *str; 124*55133Storek register int n; 125*55133Storek { 126*55133Storek register int x, y, op; 127*55133Storek 128*55133Storek x = *fb->fb_col * fb->fb_font->width + fb->fb_xorigin; 129*55133Storek y = *fb->fb_row * fb->fb_font->height + 130*55133Storek fb->fb_font_ascent + fb->fb_yorigin; 131*55133Storek op = RAS_SRC; 132*55133Storek if (((fb->fb_bits & FB_STANDOUT) != 0) ^ 133*55133Storek ((fb->fb_bits & FB_INVERT) != 0)) 134*55133Storek op = RAS_NOT(op); 135*55133Storek raster_textn(fb->fb_sp, x, y, op, fb->fb_font, str, n); 136*55133Storek *fb->fb_col += n; 137*55133Storek if (*fb->fb_col >= fb->fb_maxcol) { 138*55133Storek *fb->fb_col = 0; 139*55133Storek (*fb->fb_row)++; 140*55133Storek } 141*55133Storek if (*fb->fb_row >= fb->fb_maxrow) 142*55133Storek rcons_scroll(fb, 1); 143*55133Storek } 144*55133Storek 145*55133Storek /* Handle a control character sent to the console */ 146*55133Storek void 147*55133Storek rcons_pctrl(fb, c) 148*55133Storek register struct fbdevice *fb; 149*55133Storek register int c; 150*55133Storek { 151*55133Storek 152*55133Storek switch (c) { 153*55133Storek 154*55133Storek case '\r': /* Carriage return */ 155*55133Storek *fb->fb_col = 0; 156*55133Storek break; 157*55133Storek 158*55133Storek case '\b': /* Backspace */ 159*55133Storek if (*fb->fb_col > 0) 160*55133Storek (*fb->fb_col)--; 161*55133Storek break; 162*55133Storek 163*55133Storek case '\013': /* Vertical tab */ 164*55133Storek if (*fb->fb_row > 0) 165*55133Storek (*fb->fb_row)--; 166*55133Storek break; 167*55133Storek 168*55133Storek case '\f': /* Formfeed */ 169*55133Storek *fb->fb_row = *fb->fb_col = 0; 170*55133Storek rcons_clear2eop(fb); 171*55133Storek break; 172*55133Storek 173*55133Storek case '\n': /* Linefeed */ 174*55133Storek (*fb->fb_row)++; 175*55133Storek if (*fb->fb_row >= fb->fb_maxrow) 176*55133Storek rcons_scroll(fb, 1); 177*55133Storek break; 178*55133Storek 179*55133Storek case '\007': /* Bell */ 180*55133Storek rcons_bell(fb); 181*55133Storek break; 182*55133Storek 183*55133Storek case '\t': /* Horizontal tab */ 184*55133Storek *fb->fb_col = (*fb->fb_col + 8) & ~7; 185*55133Storek if (*fb->fb_col >= fb->fb_maxcol) 186*55133Storek *fb->fb_col = fb->fb_maxcol - 1; 187*55133Storek break; 188*55133Storek } 189*55133Storek } 190*55133Storek 191*55133Storek /* Handle the next character in an escape sequence */ 192*55133Storek void 193*55133Storek rcons_esc(fb, c) 194*55133Storek register struct fbdevice *fb; 195*55133Storek register int c; 196*55133Storek { 197*55133Storek 198*55133Storek if (c == '[') { 199*55133Storek /* Parameter 0 */ 200*55133Storek fb->fb_bits &= ~FB_P1; 201*55133Storek fb->fb_bits |= FB_P0; 202*55133Storek } else if (c == ';') { 203*55133Storek /* Parameter 1 */ 204*55133Storek fb->fb_bits &= ~FB_P0; 205*55133Storek fb->fb_bits |= FB_P1; 206*55133Storek } else if (RCONS_ISDIGIT(c)) { 207*55133Storek /* Add a digit to a parameter */ 208*55133Storek if (fb->fb_bits & FB_P0) { 209*55133Storek /* Parameter 0 */ 210*55133Storek if (fb->fb_bits & FB_P0_DEFAULT) { 211*55133Storek fb->fb_bits &= ~FB_P0_DEFAULT; 212*55133Storek fb->fb_p0 = 0; 213*55133Storek } 214*55133Storek fb->fb_p0 *= 10; 215*55133Storek fb->fb_p0 += c - '0'; 216*55133Storek } else if (fb->fb_bits & FB_P1) { 217*55133Storek /* Parameter 1 */ 218*55133Storek if (fb->fb_bits & FB_P1_DEFAULT) { 219*55133Storek fb->fb_bits &= ~FB_P1_DEFAULT; 220*55133Storek fb->fb_p1 = 0; 221*55133Storek } 222*55133Storek fb->fb_p1 *= 10; 223*55133Storek fb->fb_p1 += c - '0'; 224*55133Storek } 225*55133Storek } else { 226*55133Storek /* Erase the cursor (if necessary) */ 227*55133Storek if (fb->fb_bits & FB_CURSOR) 228*55133Storek rcons_cursor(fb); 229*55133Storek 230*55133Storek /* Process the completed escape sequence */ 231*55133Storek rcons_doesc(fb, c); 232*55133Storek fb->fb_bits &= ~FB_INESC; 233*55133Storek } 234*55133Storek } 235*55133Storek 236*55133Storek /* Process a complete escape sequence */ 237*55133Storek void 238*55133Storek rcons_doesc(fb, c) 239*55133Storek register struct fbdevice *fb; 240*55133Storek register int c; 241*55133Storek { 242*55133Storek 243*55133Storek #ifdef notdef 244*55133Storek /* XXX add escape sequence to enable visual (and audible) bell */ 245*55133Storek fb->fb_bits = FB_VISBELL; 246*55133Storek #endif 247*55133Storek 248*55133Storek switch (c) { 249*55133Storek 250*55133Storek case '@': 251*55133Storek /* Insert Character (ICH) */ 252*55133Storek rcons_insertchar(fb, fb->fb_p0); 253*55133Storek break; 254*55133Storek 255*55133Storek case 'A': 256*55133Storek /* Cursor Up (CUU) */ 257*55133Storek *fb->fb_row -= fb->fb_p0; 258*55133Storek if (*fb->fb_row < 0) 259*55133Storek *fb->fb_row = 0; 260*55133Storek break; 261*55133Storek 262*55133Storek case 'B': 263*55133Storek /* Cursor Down (CUD) */ 264*55133Storek *fb->fb_row += fb->fb_p0; 265*55133Storek if (*fb->fb_row >= fb->fb_maxrow) 266*55133Storek *fb->fb_row = fb->fb_maxrow - 1; 267*55133Storek break; 268*55133Storek 269*55133Storek case 'C': 270*55133Storek /* Cursor Forward (CUF) */ 271*55133Storek *fb->fb_col += fb->fb_p0; 272*55133Storek if (*fb->fb_col >= fb->fb_maxcol) 273*55133Storek *fb->fb_col = fb->fb_maxcol - 1; 274*55133Storek break; 275*55133Storek 276*55133Storek case 'D': 277*55133Storek /* Cursor Backward (CUB) */ 278*55133Storek *fb->fb_col -= fb->fb_p0; 279*55133Storek if (*fb->fb_col < 0) 280*55133Storek *fb->fb_col = 0; 281*55133Storek break; 282*55133Storek 283*55133Storek case 'E': 284*55133Storek /* Cursor Next Line (CNL) */ 285*55133Storek *fb->fb_col = 0; 286*55133Storek *fb->fb_row += fb->fb_p0; 287*55133Storek if (*fb->fb_row >= fb->fb_maxrow) 288*55133Storek *fb->fb_row = fb->fb_maxrow - 1; 289*55133Storek break; 290*55133Storek 291*55133Storek case 'f': 292*55133Storek /* Horizontal And Vertical Position (HVP) */ 293*55133Storek case 'H': 294*55133Storek /* Cursor Position (CUP) */ 295*55133Storek *fb->fb_col = fb->fb_p1 - 1; 296*55133Storek if (*fb->fb_col < 0) 297*55133Storek *fb->fb_col = 0; 298*55133Storek else if (*fb->fb_col >= fb->fb_maxcol) 299*55133Storek *fb->fb_col = fb->fb_maxcol - 1; 300*55133Storek 301*55133Storek *fb->fb_row = fb->fb_p0 - 1; 302*55133Storek if (*fb->fb_row < 0) 303*55133Storek *fb->fb_row = 0; 304*55133Storek else if (*fb->fb_row >= fb->fb_maxrow) 305*55133Storek *fb->fb_row = fb->fb_maxrow - 1; 306*55133Storek break; 307*55133Storek 308*55133Storek case 'J': 309*55133Storek /* Erase in Display (ED) */ 310*55133Storek rcons_clear2eop(fb); 311*55133Storek break; 312*55133Storek 313*55133Storek case 'K': 314*55133Storek /* Erase in Line (EL) */ 315*55133Storek rcons_clear2eol(fb); 316*55133Storek break; 317*55133Storek 318*55133Storek case 'L': 319*55133Storek /* Insert Line (IL) */ 320*55133Storek rcons_insertline(fb, fb->fb_p0); 321*55133Storek break; 322*55133Storek 323*55133Storek case 'M': 324*55133Storek /* Delete Line (DL) */ 325*55133Storek rcons_delline(fb, fb->fb_p0); 326*55133Storek break; 327*55133Storek 328*55133Storek case 'P': 329*55133Storek /* Delete Character (DCH) */ 330*55133Storek rcons_delchar(fb, fb->fb_p0); 331*55133Storek break; 332*55133Storek 333*55133Storek case 'm': 334*55133Storek /* Select Graphic Rendition (SGR); */ 335*55133Storek /* (defaults to zero) */ 336*55133Storek if (fb->fb_bits & FB_P0_DEFAULT) 337*55133Storek fb->fb_p0 = 0; 338*55133Storek if (fb->fb_p0) 339*55133Storek fb->fb_bits |= FB_STANDOUT; 340*55133Storek else 341*55133Storek fb->fb_bits &= ~FB_STANDOUT; 342*55133Storek break; 343*55133Storek 344*55133Storek case 'p': 345*55133Storek /* Black On White (SUNBOW) */ 346*55133Storek rcons_invert(fb, 0); 347*55133Storek break; 348*55133Storek 349*55133Storek case 'q': 350*55133Storek /* White On Black (SUNWOB) */ 351*55133Storek rcons_invert(fb, 1); 352*55133Storek break; 353*55133Storek 354*55133Storek case 'r': 355*55133Storek /* Set scrolling (SUNSCRL) */ 356*55133Storek /* (defaults to zero) */ 357*55133Storek if (fb->fb_bits & FB_P0_DEFAULT) 358*55133Storek fb->fb_p0 = 0; 359*55133Storek /* XXX not implemented yet */ 360*55133Storek fb->fb_scroll = fb->fb_p0; 361*55133Storek break; 362*55133Storek 363*55133Storek case 's': 364*55133Storek /* Reset terminal emulator (SUNRESET) */ 365*55133Storek fb->fb_bits &= ~FB_STANDOUT; 366*55133Storek fb->fb_scroll = 0; 367*55133Storek if (fb->fb_bits & FB_INVERT) 368*55133Storek rcons_invert(fb, 0); 369*55133Storek break; 370*55133Storek } 371*55133Storek } 372*55133Storek 373*55133Storek /* Paint (or unpaint) the cursor */ 374*55133Storek void 375*55133Storek rcons_cursor(fb) 376*55133Storek register struct fbdevice *fb; 377*55133Storek { 378*55133Storek register int x, y; 379*55133Storek 380*55133Storek x = *fb->fb_col * fb->fb_font->width + fb->fb_xorigin; 381*55133Storek y = *fb->fb_row * fb->fb_font->height + fb->fb_yorigin; 382*55133Storek raster_op(fb->fb_sp, x, y, 383*55133Storek #ifdef notdef 384*55133Storek /* XXX This is the right way but too slow */ 385*55133Storek fb->fb_font->chars[(int)' '].r->width, 386*55133Storek fb->fb_font->chars[(int)' '].r->height, 387*55133Storek #else 388*55133Storek fb->fb_font->width, fb->fb_font->height, 389*55133Storek #endif 390*55133Storek RAS_INVERT, (struct raster *) 0, 0, 0); 391*55133Storek fb->fb_bits ^= FB_CURSOR; 392*55133Storek } 393*55133Storek 394*55133Storek /* Possibly change to SUNWOB or SUNBOW mode */ 395*55133Storek void 396*55133Storek rcons_invert(fb, wob) 397*55133Storek struct fbdevice *fb; 398*55133Storek int wob; 399*55133Storek { 400*55133Storek if (((fb->fb_bits & FB_INVERT) != 0) ^ wob) { 401*55133Storek /* Invert the display */ 402*55133Storek raster_op(fb->fb_sp, 0, 0, fb->fb_sp->width, fb->fb_sp->height, 403*55133Storek RAS_INVERT, (struct raster *) 0, 0, 0); 404*55133Storek 405*55133Storek /* Swap things around */ 406*55133Storek fb->fb_ras_blank = RAS_NOT(fb->fb_ras_blank); 407*55133Storek fb->fb_bits ^= FB_INVERT; 408*55133Storek } 409*55133Storek } 410*55133Storek 411*55133Storek /* Clear to the end of the page */ 412*55133Storek void 413*55133Storek rcons_clear2eop(fb) 414*55133Storek register struct fbdevice *fb; 415*55133Storek { 416*55133Storek register int y; 417*55133Storek 418*55133Storek if (*fb->fb_col == 0 && *fb->fb_row == 0) { 419*55133Storek /* Clear the entire frame buffer */ 420*55133Storek raster_op(fb->fb_sp, 0, 0, 421*55133Storek fb->fb_sp->width, fb->fb_sp->height, 422*55133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0); 423*55133Storek } else { 424*55133Storek /* Only clear what needs to be cleared */ 425*55133Storek rcons_clear2eol(fb); 426*55133Storek y = (*fb->fb_row + 1) * fb->fb_font->height; 427*55133Storek 428*55133Storek raster_op(fb->fb_sp, fb->fb_xorigin, fb->fb_yorigin + y, 429*55133Storek fb->fb_emuwidth, fb->fb_emuheight - y, 430*55133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0); 431*55133Storek } 432*55133Storek } 433*55133Storek 434*55133Storek /* Clear to the end of the line */ 435*55133Storek void 436*55133Storek rcons_clear2eol(fb) 437*55133Storek register struct fbdevice *fb; 438*55133Storek { 439*55133Storek register int x; 440*55133Storek 441*55133Storek x = *fb->fb_col * fb->fb_font->width; 442*55133Storek 443*55133Storek raster_op(fb->fb_sp, 444*55133Storek fb->fb_xorigin + x, 445*55133Storek *fb->fb_row * fb->fb_font->height + fb->fb_yorigin, 446*55133Storek fb->fb_emuwidth - x, fb->fb_font->height, 447*55133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0); 448*55133Storek } 449*55133Storek 450*55133Storek /* Scroll up one line */ 451*55133Storek void 452*55133Storek rcons_scroll(fb, n) 453*55133Storek register struct fbdevice *fb; 454*55133Storek register int n; 455*55133Storek { 456*55133Storek register int ydiv; 457*55133Storek 458*55133Storek /* Can't scroll more than the whole screen */ 459*55133Storek if (n > fb->fb_maxrow) 460*55133Storek n = fb->fb_maxrow; 461*55133Storek 462*55133Storek /* Calculate new row */ 463*55133Storek *fb->fb_row -= n; 464*55133Storek if (*fb->fb_row < 0) 465*55133Storek *fb->fb_row = 0; 466*55133Storek 467*55133Storek /* Calculate number of pixels to scroll */ 468*55133Storek ydiv = fb->fb_font->height * n; 469*55133Storek 470*55133Storek raster_op(fb->fb_sp, fb->fb_xorigin, fb->fb_yorigin, 471*55133Storek fb->fb_emuwidth, fb->fb_emuheight - ydiv, 472*55133Storek RAS_SRC, fb->fb_sp, fb->fb_xorigin, ydiv + fb->fb_yorigin); 473*55133Storek 474*55133Storek raster_op(fb->fb_sp, 475*55133Storek fb->fb_xorigin, fb->fb_yorigin + fb->fb_emuheight - ydiv, 476*55133Storek fb->fb_emuwidth, ydiv, fb->fb_ras_blank, (struct raster *) 0, 0, 0); 477*55133Storek } 478*55133Storek 479*55133Storek /* Delete characters */ 480*55133Storek void 481*55133Storek rcons_delchar(fb, n) 482*55133Storek register struct fbdevice *fb; 483*55133Storek register int n; 484*55133Storek { 485*55133Storek register int tox, fromx, y, width; 486*55133Storek 487*55133Storek /* Can't delete more chars than there are */ 488*55133Storek if (n > fb->fb_maxcol - *fb->fb_col) 489*55133Storek n = fb->fb_maxcol - *fb->fb_col; 490*55133Storek 491*55133Storek fromx = (*fb->fb_col + n) * fb->fb_font->width; 492*55133Storek tox = *fb->fb_col * fb->fb_font->width; 493*55133Storek y = *fb->fb_row * fb->fb_font->height; 494*55133Storek width = n * fb->fb_font->width; 495*55133Storek 496*55133Storek raster_op(fb->fb_sp, tox + fb->fb_xorigin, y + fb->fb_yorigin, 497*55133Storek fb->fb_emuwidth - fromx, fb->fb_font->height, 498*55133Storek RAS_SRC, fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin); 499*55133Storek 500*55133Storek raster_op(fb->fb_sp, 501*55133Storek fb->fb_emuwidth - width + fb->fb_xorigin, y + fb->fb_yorigin, 502*55133Storek width, fb->fb_font->height, 503*55133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0); 504*55133Storek } 505*55133Storek 506*55133Storek /* Delete a number of lines */ 507*55133Storek void 508*55133Storek rcons_delline(fb, n) 509*55133Storek register struct fbdevice *fb; 510*55133Storek register int n; 511*55133Storek { 512*55133Storek register int fromy, toy, height; 513*55133Storek 514*55133Storek /* Can't delete more lines than there are */ 515*55133Storek if (n > fb->fb_maxrow - *fb->fb_row) 516*55133Storek n = fb->fb_maxrow - *fb->fb_row; 517*55133Storek 518*55133Storek fromy = (*fb->fb_row + n) * fb->fb_font->height; 519*55133Storek toy = *fb->fb_row * fb->fb_font->height; 520*55133Storek height = fb->fb_font->height * n; 521*55133Storek 522*55133Storek raster_op(fb->fb_sp, fb->fb_xorigin, toy + fb->fb_yorigin, 523*55133Storek fb->fb_emuwidth, fb->fb_emuheight - fromy, RAS_SRC, 524*55133Storek fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin); 525*55133Storek 526*55133Storek raster_op(fb->fb_sp, 527*55133Storek fb->fb_xorigin, fb->fb_emuheight - height + fb->fb_yorigin, 528*55133Storek fb->fb_emuwidth, height, 529*55133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0); 530*55133Storek } 531*55133Storek 532*55133Storek /* Insert some characters */ 533*55133Storek void 534*55133Storek rcons_insertchar(fb, n) 535*55133Storek register struct fbdevice *fb; 536*55133Storek register int n; 537*55133Storek { 538*55133Storek register int tox, fromx, y; 539*55133Storek 540*55133Storek /* Can't insert more chars than can fit */ 541*55133Storek if (n > fb->fb_maxcol - *fb->fb_col) 542*55133Storek n = fb->fb_maxcol - *fb->fb_col; 543*55133Storek 544*55133Storek tox = (*fb->fb_col + n) * fb->fb_font->width; 545*55133Storek fromx = *fb->fb_col * fb->fb_font->width; 546*55133Storek y = *fb->fb_row * fb->fb_font->height; 547*55133Storek 548*55133Storek raster_op(fb->fb_sp, tox + fb->fb_xorigin, y + fb->fb_yorigin, 549*55133Storek fb->fb_emuwidth - tox, fb->fb_font->height, 550*55133Storek RAS_SRC, fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin); 551*55133Storek 552*55133Storek raster_op(fb->fb_sp, fromx + fb->fb_xorigin, y + fb->fb_yorigin, 553*55133Storek fb->fb_font->width * n, fb->fb_font->height, 554*55133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0); 555*55133Storek } 556*55133Storek 557*55133Storek /* Insert some lines */ 558*55133Storek void 559*55133Storek rcons_insertline(fb, n) 560*55133Storek register struct fbdevice *fb; 561*55133Storek register int n; 562*55133Storek { 563*55133Storek register int fromy, toy; 564*55133Storek 565*55133Storek /* Can't insert more lines than can fit */ 566*55133Storek if (n > fb->fb_maxrow - *fb->fb_row) 567*55133Storek n = fb->fb_maxrow - *fb->fb_row; 568*55133Storek 569*55133Storek toy = (*fb->fb_row + n) * fb->fb_font->height; 570*55133Storek fromy = *fb->fb_row * fb->fb_font->height; 571*55133Storek 572*55133Storek raster_op(fb->fb_sp, fb->fb_xorigin, toy + fb->fb_yorigin, 573*55133Storek fb->fb_emuwidth, fb->fb_emuheight - toy, 574*55133Storek RAS_SRC, fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin); 575*55133Storek 576*55133Storek raster_op(fb->fb_sp, fb->fb_xorigin, fromy + fb->fb_yorigin, 577*55133Storek fb->fb_emuwidth, fb->fb_font->height * n, 578*55133Storek fb->fb_ras_blank, (struct raster *) 0, 0, 0); 579*55133Storek } 580