/* * * * Simple text console * * Copyright (C) 2002, 2003 Samuel Rydh (samuel@ibrium.se) * Copyright (C) 2005 Stefan Reinauer * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation * */ #include "openbios/config.h" #include "openbios/bindings.h" #include "font_8x8.c" #define FONT_ADJ_HEIGHT (FONT_HEIGHT + 2) #define NCOLS 80 #define NROWS 48 typedef enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd, ESpalette } vc_state_t; #define NPAR 16 static struct { int inited; int physw, physh; int w,h; int x,y; char *buf; int cursor_on; vc_state_t vc_state; unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */ } cons; static int get_conschar( int x, int y ) { if( (uint)x < cons.w && (uint)y < cons.h ) return cons.buf[y*cons.w + x]; return ' '; } static void draw_char( uint h, uint v ) { char *c = fontdata; int x, y, xx, rskip, m; int invert = (h==cons.x && v==cons.y && cons.cursor_on); int ch = get_conschar( h, v ); while( h >= cons.w || v >= cons.h ) return; h *= FONT_WIDTH; v *= FONT_ADJ_HEIGHT; rskip = (FONT_WIDTH > 8)? 2 : 1; c += rskip * (unsigned int)(ch & 0xff) * FONT_HEIGHT; for( x=0; x= cons.h || n < 0 ) return; for( i=0; i= '0' && ch <= '9') { cons.vc_par[cons.vc_npar] *= 10; cons.vc_par[cons.vc_npar] += ch - '0'; return; } else cons.vc_state=ESgotpars; // Fall through case ESgotpars: cons.vc_state = ESnormal; switch(ch) { case 'H': case 'f': if (cons.vc_par[0]) cons.vc_par[0]--; if (cons.vc_par[1]) cons.vc_par[1]--; cons.x = cons.vc_par[1]; cons.y = cons.vc_par[0]; return; case 'J': if (cons.vc_par[0] == 0 && (uint)cons.y < (uint)cons.h && (uint)cons.x < (uint)cons.w) { // erase from cursor to end of display for (i = cons.x; i < cons.w; i++) cons.buf[cons.y * cons.w + i] = ' '; draw_line(cons.y); for (j = cons.y + 1; j < cons.h; j++) { for (i = 0; i < cons.w; i++) cons.buf[j * cons.w + i] = ' '; draw_line(j); } } return; case 'K': switch (cons.vc_par[0]) { case 0: /* erase from cursor to end of line */ for (i = cons.x; i < cons.w; i++) cons.buf[cons.y * cons.w + i] = ' '; draw_line(cons.y); return; case 1: /* erase from start of line to cursor */ for (i = 0; i <= cons.x; i++) cons.buf[cons.y * cons.w + i] = ' '; draw_line(cons.y); return; case 2: /* erase whole line */ for (i = 0; i <= cons.w; i++) cons.buf[cons.y * cons.w + i] = ' '; draw_line(cons.y); return; default: return; } return; case 'M': scroll1(); return; case 'm': return; case '@': return; default: printk("Unhandled escape code '%c', par[%d, %d, %d, %d, %d]\n", ch, cons.vc_par[0], cons.vc_par[1], cons.vc_par[2], cons.vc_par[3], cons.vc_par[4]); return; } return; default: cons.vc_state = ESnormal; rec_char(ch, cons.x++, cons.y); return; } } int console_draw_str( const char *str ) { int ch, y, x; if( !cons.inited && console_init() ) return -1; show_cursor(0); while( (ch=*str++) ) { do_con_trol(ch); if( cons.x >= cons.w ) { cons.x=0, cons.y++; } if( cons.y >= cons.h ) { for( y=0; y