Improved console handling, thanks Stefan Weil.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2322 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
dabd98ddf5
commit
adb4796796
181
console.c
181
console.c
@ -121,6 +121,7 @@ struct TextConsole {
|
|||||||
int total_height;
|
int total_height;
|
||||||
int backscroll_height;
|
int backscroll_height;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
int x_saved, y_saved;
|
||||||
int y_displayed;
|
int y_displayed;
|
||||||
int y_base;
|
int y_base;
|
||||||
TextAttributes t_attrib_default; /* default text attributes */
|
TextAttributes t_attrib_default; /* default text attributes */
|
||||||
@ -147,7 +148,7 @@ static int nb_consoles = 0;
|
|||||||
|
|
||||||
void vga_hw_update(void)
|
void vga_hw_update(void)
|
||||||
{
|
{
|
||||||
if (active_console->hw_update)
|
if (active_console && active_console->hw_update)
|
||||||
active_console->hw_update(active_console->hw);
|
active_console->hw_update(active_console->hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,10 +660,6 @@ static void console_handle_escape(TextConsole *s)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (s->nb_esc_params == 0) { /* ESC[m sets all attributes to default */
|
|
||||||
s->t_attrib = s->t_attrib_default;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (i=0; i<s->nb_esc_params; i++) {
|
for (i=0; i<s->nb_esc_params; i++) {
|
||||||
switch (s->esc_params[i]) {
|
switch (s->esc_params[i]) {
|
||||||
case 0: /* reset all console attributes to default */
|
case 0: /* reset all console attributes to default */
|
||||||
@ -752,10 +749,21 @@ static void console_handle_escape(TextConsole *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void console_clear_xy(TextConsole *s, int x, int y)
|
||||||
|
{
|
||||||
|
int y1 = (s->y_base + y) % s->total_height;
|
||||||
|
TextCell *c = &s->cells[y1 * s->width + x];
|
||||||
|
c->ch = ' ';
|
||||||
|
c->t_attrib = s->t_attrib_default;
|
||||||
|
c++;
|
||||||
|
update_xy(s, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
static void console_putchar(TextConsole *s, int ch)
|
static void console_putchar(TextConsole *s, int ch)
|
||||||
{
|
{
|
||||||
TextCell *c;
|
TextCell *c;
|
||||||
int y1, i, x;
|
int y1, i;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
switch(s->state) {
|
switch(s->state) {
|
||||||
case TTY_STATE_NORM:
|
case TTY_STATE_NORM:
|
||||||
@ -781,20 +789,31 @@ static void console_putchar(TextConsole *s, int ch)
|
|||||||
case '\a': /* alert aka. bell */
|
case '\a': /* alert aka. bell */
|
||||||
/* TODO: has to be implemented */
|
/* TODO: has to be implemented */
|
||||||
break;
|
break;
|
||||||
|
case 14:
|
||||||
|
/* SI (shift in), character set 0 (ignored) */
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
/* SO (shift out), character set 1 (ignored) */
|
||||||
|
break;
|
||||||
case 27: /* esc (introducing an escape sequence) */
|
case 27: /* esc (introducing an escape sequence) */
|
||||||
s->state = TTY_STATE_ESC;
|
s->state = TTY_STATE_ESC;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (s->x >= s->width - 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
y1 = (s->y_base + s->y) % s->total_height;
|
y1 = (s->y_base + s->y) % s->total_height;
|
||||||
c = &s->cells[y1 * s->width + s->x];
|
c = &s->cells[y1 * s->width + s->x];
|
||||||
c->ch = ch;
|
c->ch = ch;
|
||||||
c->t_attrib = s->t_attrib;
|
c->t_attrib = s->t_attrib;
|
||||||
update_xy(s, s->x, s->y);
|
update_xy(s, s->x, s->y);
|
||||||
s->x++;
|
s->x++;
|
||||||
|
#if 0 /* line wrap disabled */
|
||||||
if (s->x >= s->width) {
|
if (s->x >= s->width) {
|
||||||
s->x = 0;
|
s->x = 0;
|
||||||
console_put_lf(s);
|
console_put_lf(s);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -818,31 +837,149 @@ static void console_putchar(TextConsole *s, int ch)
|
|||||||
s->nb_esc_params++;
|
s->nb_esc_params++;
|
||||||
if (ch == ';')
|
if (ch == ';')
|
||||||
break;
|
break;
|
||||||
|
#ifdef DEBUG_CONSOLE
|
||||||
|
fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
|
||||||
|
s->esc_params[0], s->esc_params[1], ch, s->nb_esc_params);
|
||||||
|
#endif
|
||||||
s->state = TTY_STATE_NORM;
|
s->state = TTY_STATE_NORM;
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
case 'D':
|
case 'A':
|
||||||
if (s->x > 0)
|
/* move cursor up */
|
||||||
s->x--;
|
if (s->esc_params[0] == 0) {
|
||||||
|
s->esc_params[0] = 1;
|
||||||
|
}
|
||||||
|
s->y -= s->esc_params[0];
|
||||||
|
if (s->y < 0) {
|
||||||
|
s->y = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
/* move cursor down */
|
||||||
|
if (s->esc_params[0] == 0) {
|
||||||
|
s->esc_params[0] = 1;
|
||||||
|
}
|
||||||
|
s->y += s->esc_params[0];
|
||||||
|
if (s->y >= s->height) {
|
||||||
|
s->y = s->height - 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if (s->x < (s->width - 1))
|
/* move cursor right */
|
||||||
s->x++;
|
if (s->esc_params[0] == 0) {
|
||||||
break;
|
s->esc_params[0] = 1;
|
||||||
case 'K':
|
|
||||||
/* clear to eol */
|
|
||||||
y1 = (s->y_base + s->y) % s->total_height;
|
|
||||||
for(x = s->x; x < s->width; x++) {
|
|
||||||
c = &s->cells[y1 * s->width + x];
|
|
||||||
c->ch = ' ';
|
|
||||||
c->t_attrib = s->t_attrib_default;
|
|
||||||
c++;
|
|
||||||
update_xy(s, x, s->y);
|
|
||||||
}
|
}
|
||||||
|
s->x += s->esc_params[0];
|
||||||
|
if (s->x >= s->width) {
|
||||||
|
s->x = s->width - 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
/* move cursor left */
|
||||||
|
if (s->esc_params[0] == 0) {
|
||||||
|
s->esc_params[0] = 1;
|
||||||
|
}
|
||||||
|
s->x -= s->esc_params[0];
|
||||||
|
if (s->x < 0) {
|
||||||
|
s->x = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
/* move cursor to column */
|
||||||
|
s->x = s->esc_params[0] - 1;
|
||||||
|
if (s->x < 0) {
|
||||||
|
s->x = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
case 'H':
|
||||||
|
/* move cursor to row, column */
|
||||||
|
s->x = s->esc_params[1] - 1;
|
||||||
|
if (s->x < 0) {
|
||||||
|
s->x = 0;
|
||||||
|
}
|
||||||
|
s->y = s->esc_params[0] - 1;
|
||||||
|
if (s->y < 0) {
|
||||||
|
s->y = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'J':
|
||||||
|
switch (s->esc_params[0]) {
|
||||||
|
case 0:
|
||||||
|
/* clear to end of screen */
|
||||||
|
for (y = s->y; y < s->height; y++) {
|
||||||
|
for (x = 0; x < s->width; x++) {
|
||||||
|
if (y == s->y && x < s->x) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
console_clear_xy(s, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* clear from beginning of screen */
|
||||||
|
for (y = 0; y <= s->y; y++) {
|
||||||
|
for (x = 0; x < s->width; x++) {
|
||||||
|
if (y == s->y && x > s->x) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console_clear_xy(s, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* clear entire screen */
|
||||||
|
for (y = 0; y <= s->height; y++) {
|
||||||
|
for (x = 0; x < s->width; x++) {
|
||||||
|
console_clear_xy(s, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'K':
|
||||||
|
switch (s->esc_params[0]) {
|
||||||
|
case 0:
|
||||||
|
/* clear to eol */
|
||||||
|
for(x = s->x; x < s->width; x++) {
|
||||||
|
console_clear_xy(s, x, s->y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* clear from beginning of line */
|
||||||
|
for (x = 0; x <= s->x; x++) {
|
||||||
|
console_clear_xy(s, x, s->y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* clear entire line */
|
||||||
|
for(x = 0; x < s->width; x++) {
|
||||||
|
console_clear_xy(s, x, s->y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
console_handle_escape(s);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
/* report cursor position */
|
||||||
|
/* TODO: send ESC[row;colR */
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
/* save cursor position */
|
||||||
|
s->x_saved = s->x;
|
||||||
|
s->y_saved = s->y;
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
/* restore cursor position */
|
||||||
|
s->x = s->x_saved;
|
||||||
|
s->y = s->y_saved;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#ifdef DEBUG_CONSOLE
|
||||||
|
fprintf(stderr, "unhandled escape character '%c'\n", ch);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
console_handle_escape(s);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user