2003-10-02 Till Strauman <strauman@slac.stanford.edu>

PR 502/bsps
	* console/outch.c: Add support for a few ANSI escape sequences to make
	libetcl happy.
This commit is contained in:
Joel Sherrill
2003-10-02 12:49:34 +00:00
parent d4429a7ca2
commit 0bad72c920
2 changed files with 153 additions and 20 deletions

View File

@@ -1,3 +1,9 @@
2003-10-02 Till Strauman <strauman@slac.stanford.edu>
PR 502/bsps
* console/outch.c: Add support for a few ANSI escape sequences to make
libetcl happy.
2003-09-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de> 2003-09-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Merge-in include/Makefile.am. * Makefile.am: Merge-in include/Makefile.am.

View File

@@ -10,6 +10,10 @@
* found in found in the file LICENSE in this distribution or at * found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE. * http://www.rtems.com/license/LICENSE.
* *
* Till Straumann <strauman@slac.stanford.edu>, 2003/9:
* - added handling of basic escape sequences (cursor movement
* and erasing; just enough for the line editor 'libtecla' to
* work...)
* $Id$ * $Id$
*/ */
@@ -56,27 +60,55 @@ scroll(void)
} }
static void static void
endColumn(void) doCRNL(int cr, int nl)
{ {
if (nl) {
if (++row == maxRow) { if (++row == maxRow) {
scroll(); /* Scroll the screen now */ scroll(); /* Scroll the screen now */
row = maxRow - 1; row = maxRow - 1;
} }
column = 0;
nLines++; nLines++;
}
if (cr)
column = 0;
/* Move cursor on the next location */ /* Move cursor on the next location */
wr_cursor(row * maxCol + column, ioCrtBaseAddr); if (cr || nl)
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
} }
int (*videoHook)(char, int *)=0;
static void
advanceCursor()
{
if (++column == maxCol)
doCRNL(1,1);
else
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
}
static void
gotorc(int r, int c)
{
column = c;
row = r;
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
}
#define ESC ((char)27)
/* erase current location without moving the cursor */
#define BLANK ((char)0x7f)
static void static void
videoPutChar(char car) videoPutChar(char car)
{ {
unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol; unsigned short *pt_bitmap = bitMapBaseAddr + row * maxCol + column;
switch (car) { switch (car) {
case '\b': { case '\b': {
if (column) column--; if (column) column--;
/* Move cursor on the previous location */ /* Move cursor on the previous location */
wr_cursor(row * maxCol + column, ioCrtBaseAddr); wr_cursor(row * maxCol + column, ioCrtBaseAddr);
@@ -86,10 +118,9 @@ videoPutChar(char car)
int i; int i;
i = TAB_SPACE - (column & (TAB_SPACE - 1)); i = TAB_SPACE - (column & (TAB_SPACE - 1));
pt_bitmap += column;
column += i; column += i;
if (column >= maxCol) { if (column >= maxCol) {
endColumn(); doCRNL(1,1);
return; return;
} }
while (i--) *pt_bitmap++ = ' ' | attribute; while (i--) *pt_bitmap++ = ' ' | attribute;
@@ -97,26 +128,121 @@ videoPutChar(char car)
return; return;
} }
case '\n': { case '\n': {
endColumn(); doCRNL(0,1);
return; return;
} }
case 7: { /* Bell code must be inserted here */ case 7: { /* Bell code must be inserted here */
return; return;
} }
case '\r' : { /* Already handled via \n */ case '\r' : {
doCRNL(1,0);
return; return;
} }
default: { case BLANK: {
pt_bitmap += column; *pt_bitmap = ' ' | attribute;
/* DONT move the cursor... */
return;
}
default: {
*pt_bitmap = car | attribute; *pt_bitmap = car | attribute;
if (++column == maxCol) endColumn(); advanceCursor();
else wr_cursor(row * maxCol + column,
ioCrtBaseAddr);
return; return;
} }
} }
} }
/* trivial state machine to handle escape sequences:
*
* ---------------------------------
* | |
* | |
* KEY: esc V [ DCABHKJ esc |
* STATE: 0 -----> 27 -----> '[' ----------> -1 -----
* ^\ \ \ \
* KEY: | \other \ other \ other \ other
* <-------------------------------------
*
* in state '-1', the DCABHKJ cases are handled
*
* (cursor motion and screen clearing)
*/
#define DONE (-1)
static int
handleEscape(int oldState, char car)
{
int rval = 0;
int ro,co;
switch ( oldState ) {
case DONE: /* means the previous char terminated an ESC sequence... */
case 0:
if ( 27 == car ) {
rval = 27; /* START of an ESC sequence */
}
break;
case 27:
if ( '[' == car ) {
rval = car; /* received ESC '[', so far */
} else {
/* dump suppressed 'ESC'; outch will append the char */
videoPutChar(ESC);
}
break;
case '[':
/* handle 'ESC' '[' sequences here */
ro = row; co = column;
rval = DONE; /* done */
switch (car) {
case 'D': /* left */
if ( co > 0 ) co--;
break;
case 'C': /* right */
if ( co < maxCol ) co++;
break;
case 'A': /* up */
if ( ro > 0 ) ro--;
break;
case 'B': /* down */
if ( ro < maxRow ) ro++;
break;
case 'H': /* home */
ro = co = 0;
break;
case 'K': /* clear to end of line */
while ( column < maxCol - 1 )
videoPutChar(' ');
videoPutChar(BLANK);
break;
case 'J': /* clear to end of screen */
while ( ((row < maxRow-1) || (column < maxCol-1)) )
videoPutChar(' ');
videoPutChar(BLANK);
break;
default:
videoPutChar(ESC);
videoPutChar('[');
/* DONT move the cursor */
ro = -1;
rval = 0;
break;
}
/* reset cursor */
if ( ro >= 0)
gotorc(ro,co);
default:
break;
}
return rval;
}
void void
clear_screen(void) clear_screen(void)
{ {
@@ -141,7 +267,10 @@ clear_screen(void)
void void
_IBMPC_outch(char c) _IBMPC_outch(char c)
{ {
videoPutChar(c); static int escaped = 0;
if ( ! (escaped = handleEscape(escaped, c)) )
videoPutChar(c);
} /* _IBMPC_outch */ } /* _IBMPC_outch */
@@ -184,9 +313,7 @@ _IBMPC_initVideo(void)
/* for old DOS compatibility n-curses type of applications */ /* for old DOS compatibility n-curses type of applications */
void gotoxy( int x, int y ) void gotoxy( int x, int y )
{ {
row = x; gotorc(y,x);
column = y;
wr_cursor(row * maxCol + column, ioCrtBaseAddr);
} }