@ -385,6 +385,13 @@ static u32 eorx, fgx, bgx; /* color pats */
static int cfb_do_flush_cache ;
# ifdef CONFIG_CFB_CONSOLE_ANSI
static char ansi_buf [ 10 ] ;
static int ansi_buf_size ;
static int ansi_colors_need_revert ;
static int ansi_cursor_hidden ;
# endif
static const int video_font_draw_table8 [ ] = {
0x00000000 , 0x000000ff , 0x0000ff00 , 0x0000ffff ,
0x00ff0000 , 0x00ff00ff , 0x00ffff00 , 0x00ffffff ,
@ -768,9 +775,97 @@ static void console_back(void)
}
}
static void console_newline ( void )
# ifdef CONFIG_CFB_CONSOLE_ANSI
static void console_clear ( void )
{
# ifdef VIDEO_HW_RECTFILL
video_hw_rectfill ( VIDEO_PIXEL_SIZE , /* bytes per pixel */
0 , /* dest pos x */
video_logo_height , /* dest pos y */
VIDEO_VISIBLE_COLS , /* frame width */
VIDEO_VISIBLE_ROWS , /* frame height */
bgx /* fill color */
) ;
# else
memsetl ( CONSOLE_ROW_FIRST , CONSOLE_SIZE , bgx ) ;
# endif
}
static void console_cursor_fix ( void )
{
if ( console_row < 0 )
console_row = 0 ;
if ( console_row > = CONSOLE_ROWS )
console_row = CONSOLE_ROWS - 1 ;
if ( console_col < 0 )
console_col = 0 ;
if ( console_col > = CONSOLE_COLS )
console_col = CONSOLE_COLS - 1 ;
}
static void console_cursor_up ( int n )
{
console_row - = n ;
console_cursor_fix ( ) ;
}
static void console_cursor_down ( int n )
{
console_row + = n ;
console_cursor_fix ( ) ;
}
static void console_cursor_left ( int n )
{
console_col - = n ;
console_cursor_fix ( ) ;
}
static void console_cursor_right ( int n )
{
console_col + = n ;
console_cursor_fix ( ) ;
}
static void console_cursor_set_position ( int row , int col )
{
if ( console_row ! = - 1 )
console_row = row ;
if ( console_col ! = - 1 )
console_col = col ;
console_cursor_fix ( ) ;
}
static void console_previousline ( int n )
{
console_row + + ;
/* FIXME: also scroll terminal ? */
console_row - = n ;
console_cursor_fix ( ) ;
}
static void console_swap_colors ( void )
{
eorx = fgx ;
fgx = bgx ;
bgx = eorx ;
eorx = fgx ^ bgx ;
}
static inline int console_cursor_is_visible ( void )
{
return ! ansi_cursor_hidden ;
}
# else
static inline int console_cursor_is_visible ( void )
{
return 1 ;
}
# endif
static void console_newline ( int n )
{
console_row + = n ;
console_col = 0 ;
/* Check if we need to scroll the terminal */
@ -779,7 +874,7 @@ static void console_newline(void)
console_scrollup ( ) ;
/* Decrement row number */
console_row - - ;
console_row = CONSOLE_ROWS - 1 ;
}
}
@ -788,11 +883,12 @@ static void console_cr(void)
console_col = 0 ;
}
void video _putc( const char c )
static void parse _putc( const char c )
{
static int nl = 1 ;
CURSOR_OFF ;
if ( console_cursor_is_visible ( ) )
CURSOR_OFF ;
switch ( c ) {
case 13 : /* back to first column */
@ -801,7 +897,7 @@ void video_putc(const char c)
case ' \n ' : /* next line */
if ( console_col | | ( ! console_col & & nl ) )
console_newline ( ) ;
console_newline ( 1 ) ;
nl = 1 ;
break ;
@ -810,7 +906,7 @@ void video_putc(const char c)
console_col & = ~ 0x0007 ;
if ( console_col > = CONSOLE_COLS )
console_newline ( ) ;
console_newline ( 1 ) ;
break ;
case 8 : /* backspace */
@ -827,11 +923,225 @@ void video_putc(const char c)
/* check for newline */
if ( console_col > = CONSOLE_COLS ) {
console_newline ( ) ;
console_newline ( 1 ) ;
nl = 0 ;
}
}
CURSOR_SET ;
if ( console_cursor_is_visible ( ) )
CURSOR_SET ;
}
void video_putc ( const char c )
{
# ifdef CONFIG_CFB_CONSOLE_ANSI
int i ;
if ( c = = 27 ) {
for ( i = 0 ; i < ansi_buf_size ; + + i )
parse_putc ( ansi_buf [ i ] ) ;
ansi_buf [ 0 ] = 27 ;
ansi_buf_size = 1 ;
return ;
}
if ( ansi_buf_size > 0 ) {
/*
* 0 - ESC
* 1 - [
* 2 - num1
* 3 - . .
* 4 - ;
* 5 - num2
* 6 - . .
* - cchar
*/
int next = 0 ;
int flush = 0 ;
int fail = 0 ;
int num1 = 0 ;
int num2 = 0 ;
int cchar = 0 ;
ansi_buf [ ansi_buf_size + + ] = c ;
if ( ansi_buf_size > = sizeof ( ansi_buf ) )
fail = 1 ;
for ( i = 0 ; i < ansi_buf_size ; + + i ) {
if ( fail )
break ;
switch ( next ) {
case 0 :
if ( ansi_buf [ i ] = = 27 )
next = 1 ;
else
fail = 1 ;
break ;
case 1 :
if ( ansi_buf [ i ] = = ' [ ' )
next = 2 ;
else
fail = 1 ;
break ;
case 2 :
if ( ansi_buf [ i ] > = ' 0 ' & & ansi_buf [ i ] < = ' 9 ' ) {
num1 = ansi_buf [ i ] - ' 0 ' ;
next = 3 ;
} else if ( ansi_buf [ i ] ! = ' ? ' ) {
- - i ;
num1 = 1 ;
next = 4 ;
}
break ;
case 3 :
if ( ansi_buf [ i ] > = ' 0 ' & & ansi_buf [ i ] < = ' 9 ' ) {
num1 * = 10 ;
num1 + = ansi_buf [ i ] - ' 0 ' ;
} else {
- - i ;
next = 4 ;
}
break ;
case 4 :
if ( ansi_buf [ i ] ! = ' ; ' ) {
- - i ;
next = 7 ;
} else
next = 5 ;
break ;
case 5 :
if ( ansi_buf [ i ] > = ' 0 ' & & ansi_buf [ i ] < = ' 9 ' ) {
num2 = ansi_buf [ i ] - ' 0 ' ;
next = 6 ;
} else
fail = 1 ;
break ;
case 6 :
if ( ansi_buf [ i ] > = ' 0 ' & & ansi_buf [ i ] < = ' 9 ' ) {
num2 * = 10 ;
num2 + = ansi_buf [ i ] - ' 0 ' ;
} else {
- - i ;
next = 7 ;
}
break ;
case 7 :
if ( ( ansi_buf [ i ] > = ' A ' & & ansi_buf [ i ] < = ' H ' )
| | ansi_buf [ i ] = = ' J '
| | ansi_buf [ i ] = = ' K '
| | ansi_buf [ i ] = = ' h '
| | ansi_buf [ i ] = = ' l '
| | ansi_buf [ i ] = = ' m ' ) {
cchar = ansi_buf [ i ] ;
flush = 1 ;
} else
fail = 1 ;
break ;
}
}
if ( fail ) {
for ( i = 0 ; i < ansi_buf_size ; + + i )
parse_putc ( ansi_buf [ i ] ) ;
ansi_buf_size = 0 ;
return ;
}
if ( flush ) {
if ( ! ansi_cursor_hidden )
CURSOR_OFF ;
ansi_buf_size = 0 ;
switch ( cchar ) {
case ' A ' :
/* move cursor num1 rows up */
console_cursor_up ( num1 ) ;
break ;
case ' B ' :
/* move cursor num1 rows down */
console_cursor_down ( num1 ) ;
break ;
case ' C ' :
/* move cursor num1 columns forward */
console_cursor_right ( num1 ) ;
break ;
case ' D ' :
/* move cursor num1 columns back */
console_cursor_left ( num1 ) ;
break ;
case ' E ' :
/* move cursor num1 rows up at begin of row */
console_previousline ( num1 ) ;
break ;
case ' F ' :
/* move cursor num1 rows down at begin of row */
console_newline ( num1 ) ;
break ;
case ' G ' :
/* move cursor to column num1 */
console_cursor_set_position ( - 1 , num1 - 1 ) ;
break ;
case ' H ' :
/* move cursor to row num1, column num2 */
console_cursor_set_position ( num1 - 1 , num2 - 1 ) ;
break ;
case ' J ' :
/* clear console and move cursor to 0, 0 */
console_clear ( ) ;
console_cursor_set_position ( 0 , 0 ) ;
break ;
case ' K ' :
/* clear line */
if ( num1 = = 0 )
console_clear_line ( console_row ,
console_col ,
CONSOLE_COLS - 1 ) ;
else if ( num1 = = 1 )
console_clear_line ( console_row ,
0 , console_col ) ;
else
console_clear_line ( console_row ,
0 , CONSOLE_COLS - 1 ) ;
break ;
case ' h ' :
ansi_cursor_hidden = 0 ;
break ;
case ' l ' :
ansi_cursor_hidden = 1 ;
break ;
case ' m ' :
if ( num1 = = 0 ) { /* reset swapped colors */
if ( ansi_colors_need_revert ) {
console_swap_colors ( ) ;
ansi_colors_need_revert = 0 ;
}
} else if ( num1 = = 7 ) { /* once swap colors */
if ( ! ansi_colors_need_revert ) {
console_swap_colors ( ) ;
ansi_colors_need_revert = 1 ;
}
}
break ;
}
if ( ! ansi_cursor_hidden )
CURSOR_SET ;
}
} else {
parse_putc ( c ) ;
}
# else
parse_putc ( c ) ;
# endif
}
void video_puts ( const char * s )